Commit 81b068e13e0a2b4e0cc7eb177dac337302233d82
1 parent
e484c624
Exists in
master
and in
3 other branches
creating subject functional and breadcrumbs ok
Showing
13 changed files
with
270 additions
and
17 deletions
Show diff stats
categories/forms.py
@@ -6,7 +6,7 @@ class CategoryForm(forms.ModelForm): | @@ -6,7 +6,7 @@ class CategoryForm(forms.ModelForm): | ||
6 | model = Category | 6 | model = Category |
7 | fields = ( 'name', 'description', 'visible', 'coordinators', ) | 7 | fields = ( 'name', 'description', 'visible', 'coordinators', ) |
8 | widgets = { | 8 | widgets = { |
9 | - 'description': forms.Textarea, | ||
10 | - 'coordinators' : forms.SelectMultiple, | ||
11 | - } | ||
12 | - | ||
13 | \ No newline at end of file | 9 | \ No newline at end of file |
10 | + 'description': forms.Textarea, | ||
11 | + 'coordinators' : forms.SelectMultiple, | ||
12 | + } | ||
13 | + | ||
14 | \ No newline at end of file | 14 | \ No newline at end of file |
categories/views.py
@@ -128,7 +128,7 @@ class CreateCategory(views.SuperuserRequiredMixin, HasRoleMixin, LogMixin, Creat | @@ -128,7 +128,7 @@ class CreateCategory(views.SuperuserRequiredMixin, HasRoleMixin, LogMixin, Creat | ||
128 | return super(CreateCategory, self).form_valid(form) | 128 | return super(CreateCategory, self).form_valid(form) |
129 | 129 | ||
130 | def get_success_url(self): | 130 | def get_success_url(self): |
131 | - print(self.object.coordinators) | 131 | + |
132 | objeto = self.object.name | 132 | objeto = self.object.name |
133 | messages.success(self.request, _('Category "%s" register successfully!')%(objeto)) | 133 | messages.success(self.request, _('Category "%s" register successfully!')%(objeto)) |
134 | return reverse_lazy('categories:index') | 134 | return reverse_lazy('categories:index') |
subjects/admin.py
@@ -4,7 +4,7 @@ from .models import Subject, Marker | @@ -4,7 +4,7 @@ from .models import Subject, Marker | ||
4 | from .forms import CreateSubjectForm, CreateMarkerForm | 4 | from .forms import CreateSubjectForm, CreateMarkerForm |
5 | 5 | ||
6 | class SubjectAdmin(admin.ModelAdmin): | 6 | class SubjectAdmin(admin.ModelAdmin): |
7 | - list_display = ['name', 'description_brief', 'description', 'init_date', 'end_date', 'visible', 'professor',] | 7 | + list_display = ['name', 'description_brief', 'description', 'init_date', 'end_date', 'visible',] |
8 | search_fields = ['name'] | 8 | search_fields = ['name'] |
9 | form = CreateSubjectForm | 9 | form = CreateSubjectForm |
10 | 10 |
subjects/forms.py
@@ -2,10 +2,17 @@ from .models import Subject, Marker | @@ -2,10 +2,17 @@ from .models import Subject, Marker | ||
2 | from django import forms | 2 | from django import forms |
3 | class CreateSubjectForm(forms.ModelForm): | 3 | class CreateSubjectForm(forms.ModelForm): |
4 | # TODO: Define form fields here | 4 | # TODO: Define form fields here |
5 | - model = Subject | 5 | + class Meta: |
6 | + model = Subject | ||
7 | + | ||
8 | + fields = ('name', 'description_brief', 'description', 'markers', 'init_date', 'end_date', 'visible', 'professor', | ||
9 | + 'students', ) | ||
10 | + | ||
11 | + widgets = { | ||
12 | + 'professor': forms.SelectMultiple, | ||
13 | + 'students': forms.SelectMultiple, | ||
14 | + } | ||
6 | 15 | ||
7 | - fields = ('name', 'description_brief', 'description', 'init_date', 'end_date', 'visible', 'markers', 'professor', | ||
8 | - 'students', 'category', ) | ||
9 | 16 | ||
10 | 17 | ||
11 | class CreateMarkerForm(forms.ModelForm): | 18 | class CreateMarkerForm(forms.ModelForm): |
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +# Generated by Django 1.10 on 2017-01-02 20:27 | ||
3 | +from __future__ import unicode_literals | ||
4 | + | ||
5 | +from django.conf import settings | ||
6 | +from django.db import migrations, models | ||
7 | +import django.db.models.deletion | ||
8 | + | ||
9 | + | ||
10 | +class Migration(migrations.Migration): | ||
11 | + | ||
12 | + dependencies = [ | ||
13 | + ('subjects', '0002_auto_20161226_2054'), | ||
14 | + ] | ||
15 | + | ||
16 | + operations = [ | ||
17 | + migrations.AlterField( | ||
18 | + model_name='subject', | ||
19 | + name='description', | ||
20 | + field=models.CharField(blank=True, max_length=300, verbose_name='description'), | ||
21 | + ), | ||
22 | + migrations.AlterField( | ||
23 | + model_name='subject', | ||
24 | + name='description_brief', | ||
25 | + field=models.CharField(blank=True, max_length=100, verbose_name='simpler_description'), | ||
26 | + ), | ||
27 | + migrations.AlterField( | ||
28 | + model_name='subject', | ||
29 | + name='markers', | ||
30 | + field=models.ManyToManyField(blank=True, null=True, to='subjects.Marker', verbose_name='markers'), | ||
31 | + ), | ||
32 | + migrations.AlterField( | ||
33 | + model_name='subject', | ||
34 | + name='max_upload_size', | ||
35 | + field=models.IntegerField(default=1024, null=True, verbose_name='Maximum upload size'), | ||
36 | + ), | ||
37 | + migrations.AlterField( | ||
38 | + model_name='subject', | ||
39 | + name='professor', | ||
40 | + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='professor', to=settings.AUTH_USER_MODEL), | ||
41 | + ), | ||
42 | + ] |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +# Generated by Django 1.10 on 2017-01-02 20:37 | ||
3 | +from __future__ import unicode_literals | ||
4 | + | ||
5 | +from django.db import migrations, models | ||
6 | +import django.db.models.deletion | ||
7 | + | ||
8 | + | ||
9 | +class Migration(migrations.Migration): | ||
10 | + | ||
11 | + dependencies = [ | ||
12 | + ('subjects', '0003_auto_20170102_1727'), | ||
13 | + ] | ||
14 | + | ||
15 | + operations = [ | ||
16 | + migrations.AlterField( | ||
17 | + model_name='subject', | ||
18 | + name='category', | ||
19 | + field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='subject_category', to='categories.Category'), | ||
20 | + ), | ||
21 | + ] |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +# Generated by Django 1.10 on 2017-01-02 20:37 | ||
3 | +from __future__ import unicode_literals | ||
4 | + | ||
5 | +from django.db import migrations, models | ||
6 | +import django.db.models.deletion | ||
7 | + | ||
8 | + | ||
9 | +class Migration(migrations.Migration): | ||
10 | + | ||
11 | + dependencies = [ | ||
12 | + ('subjects', '0004_auto_20170102_1737'), | ||
13 | + ] | ||
14 | + | ||
15 | + operations = [ | ||
16 | + migrations.AlterField( | ||
17 | + model_name='subject', | ||
18 | + name='category', | ||
19 | + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subject_category', to='categories.Category'), | ||
20 | + ), | ||
21 | + ] |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +# Generated by Django 1.10 on 2017-01-02 20:39 | ||
3 | +from __future__ import unicode_literals | ||
4 | + | ||
5 | +from django.conf import settings | ||
6 | +from django.db import migrations, models | ||
7 | + | ||
8 | + | ||
9 | +class Migration(migrations.Migration): | ||
10 | + | ||
11 | + dependencies = [ | ||
12 | + migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
13 | + ('subjects', '0005_auto_20170102_1737'), | ||
14 | + ] | ||
15 | + | ||
16 | + operations = [ | ||
17 | + migrations.RemoveField( | ||
18 | + model_name='subject', | ||
19 | + name='professor', | ||
20 | + ), | ||
21 | + migrations.AddField( | ||
22 | + model_name='subject', | ||
23 | + name='professor', | ||
24 | + field=models.ManyToManyField(blank=True, related_name='professor', to=settings.AUTH_USER_MODEL), | ||
25 | + ), | ||
26 | + ] |
subjects/models.py
@@ -18,24 +18,24 @@ class Subject(models.Model): | @@ -18,24 +18,24 @@ class Subject(models.Model): | ||
18 | name = models.CharField( _("Name"), unique = True,max_length= 200) | 18 | name = models.CharField( _("Name"), unique = True,max_length= 200) |
19 | slug = AutoSlugField(_("Slug"),populate_from='name',unique=True) | 19 | slug = AutoSlugField(_("Slug"),populate_from='name',unique=True) |
20 | 20 | ||
21 | - description_brief = models.CharField(_("simpler_description"), max_length= 100) | ||
22 | - description = models.CharField(_("description"), max_length = 300) | 21 | + description_brief = models.CharField(_("simpler_description"), max_length= 100, blank=True) |
22 | + description = models.CharField(_("description"), max_length = 300, blank= True) | ||
23 | visible = models.BooleanField(_("visible")) | 23 | visible = models.BooleanField(_("visible")) |
24 | 24 | ||
25 | init_date = models.DateField(_('Begin of Subject Date')) | 25 | init_date = models.DateField(_('Begin of Subject Date')) |
26 | end_date = models.DateField(_('End of Subject Date')) | 26 | end_date = models.DateField(_('End of Subject Date')) |
27 | 27 | ||
28 | - markers = models.ManyToManyField(Marker, verbose_name='markers') | 28 | + markers = models.ManyToManyField(Marker, verbose_name='markers', blank=True, null=True) |
29 | 29 | ||
30 | create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True) | 30 | create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True) |
31 | update_date = models.DateTimeField(_('Date of last update'), auto_now=True) | 31 | update_date = models.DateTimeField(_('Date of last update'), auto_now=True) |
32 | 32 | ||
33 | - professor = models.ForeignKey(User, related_name="professor") | 33 | + professor = models.ManyToManyField(User, related_name="professor", blank=True) |
34 | students = models.ManyToManyField(User,verbose_name=_('Students'), related_name='subject_student', blank = True) | 34 | students = models.ManyToManyField(User,verbose_name=_('Students'), related_name='subject_student', blank = True) |
35 | 35 | ||
36 | - category = models.ForeignKey(Category, related_name="subject_category") | 36 | + category = models.ForeignKey(Category, related_name="subject_category", null=True) |
37 | 37 | ||
38 | - max_upload_size = models.IntegerField(_("Maximum upload size")) | 38 | + max_upload_size = models.IntegerField(_("Maximum upload size"), default=1024, null=True) |
39 | class Meta: | 39 | class Meta: |
40 | verbose_name = "Subject" | 40 | verbose_name = "Subject" |
41 | verbose_name_plural = "Subjects" | 41 | verbose_name_plural = "Subjects" |
@@ -0,0 +1,94 @@ | @@ -0,0 +1,94 @@ | ||
1 | +{% extends 'categories/create.html' %} | ||
2 | + | ||
3 | + | ||
4 | + | ||
5 | +{% load widget_tweaks static i18n permission_tags django_bootstrap_breadcrumbs switchevenodd %} | ||
6 | + | ||
7 | + | ||
8 | +{% block breadcrumbs %} | ||
9 | + {% clear_breadcrumbs %} | ||
10 | + {% breadcrumb 'Home' 'categories:index' %} | ||
11 | + | ||
12 | + {% breadcrumb slug 'categories:index' %} | ||
13 | + {% breadcrumb 'Create Subject' 'subjects:create' %} | ||
14 | +{% endblock %} | ||
15 | + | ||
16 | +{% block content %} | ||
17 | + {{ block.super }} | ||
18 | + | ||
19 | + | ||
20 | + <script type="text/javascript"> | ||
21 | + $('#id_professor').multiSelect({ | ||
22 | + selectableHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=' '>", | ||
23 | + selectionHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=''>", | ||
24 | + afterInit: function(ms){ | ||
25 | + var that = this, | ||
26 | + $selectableSearch = that.$selectableUl.prev(), | ||
27 | + $selectionSearch = that.$selectionUl.prev(), | ||
28 | + selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)', | ||
29 | + selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected'; | ||
30 | + | ||
31 | + that.qs1 = $selectableSearch.quicksearch(selectableSearchString) | ||
32 | + .on('keydown', function(e){ | ||
33 | + if (e.which === 40){ | ||
34 | + that.$selectableUl.focus(); | ||
35 | + return false; | ||
36 | + } | ||
37 | + }); | ||
38 | + | ||
39 | + that.qs2 = $selectionSearch.quicksearch(selectionSearchString) | ||
40 | + .on('keydown', function(e){ | ||
41 | + if (e.which == 40){ | ||
42 | + that.$selectionUl.focus(); | ||
43 | + return false; | ||
44 | + } | ||
45 | + }); | ||
46 | + }, | ||
47 | + afterSelect: function(){ | ||
48 | + this.qs1.cache(); | ||
49 | + this.qs2.cache(); | ||
50 | + }, | ||
51 | + afterDeselect: function(){ | ||
52 | + this.qs1.cache(); | ||
53 | + this.qs2.cache(); | ||
54 | + } | ||
55 | + });// Used to create multi-select css style | ||
56 | + | ||
57 | + $('#id_students').multiSelect({ | ||
58 | + selectableHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=' '>", | ||
59 | + selectionHeader: "<input type='text' class='search-input category-search-users' autocomplete='off' placeholder=''>", | ||
60 | + afterInit: function(ms){ | ||
61 | + var that = this, | ||
62 | + $selectableSearch = that.$selectableUl.prev(), | ||
63 | + $selectionSearch = that.$selectionUl.prev(), | ||
64 | + selectableSearchString = '#'+that.$container.attr('id')+' .ms-elem-selectable:not(.ms-selected)', | ||
65 | + selectionSearchString = '#'+that.$container.attr('id')+' .ms-elem-selection.ms-selected'; | ||
66 | + | ||
67 | + that.qs1 = $selectableSearch.quicksearch(selectableSearchString) | ||
68 | + .on('keydown', function(e){ | ||
69 | + if (e.which === 40){ | ||
70 | + that.$selectableUl.focus(); | ||
71 | + return false; | ||
72 | + } | ||
73 | + }); | ||
74 | + | ||
75 | + that.qs2 = $selectionSearch.quicksearch(selectionSearchString) | ||
76 | + .on('keydown', function(e){ | ||
77 | + if (e.which == 40){ | ||
78 | + that.$selectionUl.focus(); | ||
79 | + return false; | ||
80 | + } | ||
81 | + }); | ||
82 | + }, | ||
83 | + afterSelect: function(){ | ||
84 | + this.qs1.cache(); | ||
85 | + this.qs2.cache(); | ||
86 | + }, | ||
87 | + afterDeselect: function(){ | ||
88 | + this.qs1.cache(); | ||
89 | + this.qs2.cache(); | ||
90 | + } | ||
91 | + });// Used to create multi-select css style | ||
92 | + </script> | ||
93 | +{% endblock content %} | ||
94 | + |
subjects/templates/subjects/list.html
@@ -86,7 +86,7 @@ | @@ -86,7 +86,7 @@ | ||
86 | 86 | ||
87 | {{category.description|safe}} | 87 | {{category.description|safe}} |
88 | {% if user in category.coordinators.all %} | 88 | {% if user in category.coordinators.all %} |
89 | - <button class="create-subject-btn"> {% trans "create new subject" %} </button> | 89 | + <a href="{% url 'subjects:create' category.slug %}"><button class="create-subject-btn"> {% trans "create new subject" %} </button></a> |
90 | {% endif %} | 90 | {% endif %} |
91 | 91 | ||
92 | </div> | 92 | </div> |
subjects/urls.py
@@ -3,4 +3,5 @@ from . import views | @@ -3,4 +3,5 @@ from . import views | ||
3 | 3 | ||
4 | urlpatterns = [ | 4 | urlpatterns = [ |
5 | url(r'^$', views.IndexView.as_view(), name='index'), | 5 | url(r'^$', views.IndexView.as_view(), name='index'), |
6 | + url(r'^create/(?P<slug>[\w_-]+)/$', views.SubjectCreateView.as_view(), name='create'), | ||
6 | ] | 7 | ] |
7 | \ No newline at end of file | 8 | \ No newline at end of file |
subjects/views.py
@@ -23,6 +23,7 @@ from log.models import Log | @@ -23,6 +23,7 @@ from log.models import Log | ||
23 | 23 | ||
24 | import time | 24 | import time |
25 | 25 | ||
26 | +from .forms import CreateSubjectForm | ||
26 | from users.models import User | 27 | from users.models import User |
27 | 28 | ||
28 | 29 | ||
@@ -57,9 +58,49 @@ class IndexView(LoginRequiredMixin, ListView): | @@ -57,9 +58,49 @@ class IndexView(LoginRequiredMixin, ListView): | ||
57 | 58 | ||
58 | def get_context_data(self, **kwargs): | 59 | def get_context_data(self, **kwargs): |
59 | context = super(IndexView, self).get_context_data(**kwargs) | 60 | context = super(IndexView, self).get_context_data(**kwargs) |
60 | - categories = self.get_queryset().order_by('name') | 61 | + if self.request.user.is_staff: |
62 | + categories = self.get_queryset().order_by('name') | ||
63 | + else: | ||
64 | + categories = self.get_queryset().order_by('name').filter(visible=True) | ||
61 | 65 | ||
62 | 66 | ||
63 | context['categories'] = categories | 67 | context['categories'] = categories |
64 | 68 | ||
65 | return context | 69 | return context |
70 | + | ||
71 | +class SubjectCreateView(CreateView): | ||
72 | + model = Subject | ||
73 | + template_name = "subjects/create.html" | ||
74 | + | ||
75 | + login_url = reverse_lazy('users:login') | ||
76 | + form_class = CreateSubjectForm | ||
77 | + | ||
78 | + success_url = reverse_lazy('subject:index') | ||
79 | + | ||
80 | + def get_initial(self): | ||
81 | + initial = super(SubjectCreateView, self).get_initial() | ||
82 | + initial['category'] = Category.objects.all().filter(slug=self.kwargs['slug']) | ||
83 | + | ||
84 | + return initial | ||
85 | + | ||
86 | + def get_context_data(self, **kwargs): | ||
87 | + context = super(SubjectCreateView, self).get_context_data(**kwargs) | ||
88 | + context['slug'] = self.kwargs['slug'] | ||
89 | + return context | ||
90 | + def form_valid(self, form): | ||
91 | + | ||
92 | + self.object = form.save() | ||
93 | + self.object.category = Category.objects.get(slug=self.kwargs['slug']) | ||
94 | + self.object.save() | ||
95 | + | ||
96 | + | ||
97 | + return super(SubjectCreateView, self).form_valid(form) | ||
98 | + | ||
99 | + def get_success_url(self): | ||
100 | + | ||
101 | + | ||
102 | + objeto = self.object.name | ||
103 | + messages.success(self.request, _('Subject "%s" registered successfully!')%(objeto)) | ||
104 | + return reverse_lazy('subjects:index') | ||
105 | + | ||
106 | + |