diff options
Diffstat (limited to 'proposals')
-rw-r--r-- | proposals/__init__.py | 0 | ||||
-rw-r--r-- | proposals/admin.py | 12 | ||||
-rw-r--r-- | proposals/forms.py | 10 | ||||
-rw-r--r-- | proposals/models.py | 75 | ||||
-rw-r--r-- | proposals/templatetags/icons.py | 14 | ||||
-rw-r--r-- | proposals/tests.py | 16 | ||||
-rw-r--r-- | proposals/urls.py | 9 | ||||
-rw-r--r-- | proposals/views.py | 30 |
8 files changed, 166 insertions, 0 deletions
diff --git a/proposals/__init__.py b/proposals/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/proposals/__init__.py | |||
diff --git a/proposals/admin.py b/proposals/admin.py new file mode 100644 index 0000000..5b10ec3 --- /dev/null +++ b/proposals/admin.py | |||
@@ -0,0 +1,12 @@ | |||
1 | from django.contrib import admin | ||
2 | |||
3 | from proposals.models import TimeSlot, Location, TalkType | ||
4 | from proposals.models import AudienceSkillLevel, Category, Proposal | ||
5 | |||
6 | |||
7 | admin.site.register(Category) | ||
8 | admin.site.register(TimeSlot) | ||
9 | admin.site.register(Location) | ||
10 | admin.site.register(Proposal) | ||
11 | admin.site.register(TalkType) | ||
12 | admin.site.register(AudienceSkillLevel) | ||
diff --git a/proposals/forms.py b/proposals/forms.py new file mode 100644 index 0000000..7a32dec --- /dev/null +++ b/proposals/forms.py | |||
@@ -0,0 +1,10 @@ | |||
1 | from django import forms | ||
2 | |||
3 | from proposals.models import Proposal | ||
4 | |||
5 | |||
6 | class UserProposalForm(forms.ModelForm): | ||
7 | |||
8 | class Meta: | ||
9 | model = Proposal | ||
10 | exclude = ("approved", "location", "time_slot") | ||
diff --git a/proposals/models.py b/proposals/models.py new file mode 100644 index 0000000..8551659 --- /dev/null +++ b/proposals/models.py | |||
@@ -0,0 +1,75 @@ | |||
1 | from django.db import models | ||
2 | from django.contrib.auth.models import User | ||
3 | |||
4 | |||
5 | class TimeSlot(models.Model): | ||
6 | |||
7 | slot = models.DateTimeField() | ||
8 | |||
9 | def __str__(self): | ||
10 | return self.slot.strftime("%A, %B %d, %Y @ %I:%M %p") | ||
11 | |||
12 | |||
13 | class Location(models.Model): | ||
14 | |||
15 | name = models.CharField(max_length=255) | ||
16 | |||
17 | def __str__(self): | ||
18 | return self.name | ||
19 | |||
20 | |||
21 | class TalkType(models.Model): | ||
22 | |||
23 | name = models.CharField(max_length=255) | ||
24 | |||
25 | def __str__(self): | ||
26 | return self.name | ||
27 | |||
28 | |||
29 | class AudienceSkillLevel(models.Model): | ||
30 | |||
31 | name = models.CharField(max_length=255) | ||
32 | |||
33 | def __str__(self): | ||
34 | return self.name | ||
35 | |||
36 | |||
37 | class Category(models.Model): | ||
38 | |||
39 | name = models.CharField(max_length=255) | ||
40 | |||
41 | def __str__(self): | ||
42 | return self.name | ||
43 | |||
44 | class Meta: | ||
45 | verbose_name_plural = "Categories" | ||
46 | |||
47 | |||
48 | class ProposalManager(models.Manager): | ||
49 | |||
50 | def for_user(self, user): | ||
51 | return self.get_query_set().filter(proposers=user) | ||
52 | |||
53 | |||
54 | class Proposal(models.Model): | ||
55 | |||
56 | objects = ProposalManager() | ||
57 | |||
58 | title = models.CharField(max_length=255) | ||
59 | |||
60 | type = models.ForeignKey(TalkType) | ||
61 | category = models.ForeignKey(Category) | ||
62 | audience_skill_level = models.ForeignKey(AudienceSkillLevel) | ||
63 | location = models.ForeignKey(Location, blank=True, null=True) | ||
64 | time_slot = models.ForeignKey(TimeSlot, blank=True, null=True) | ||
65 | proposers = models.ManyToManyField(User) | ||
66 | |||
67 | approved = models.BooleanField(default=False) | ||
68 | recording_release = models.BooleanField(default=False) | ||
69 | |||
70 | outline = models.TextField(blank=True) | ||
71 | abstract = models.TextField(blank=True) | ||
72 | notes = models.TextField(blank=True) | ||
73 | |||
74 | def __str__(self): | ||
75 | return self.title | ||
diff --git a/proposals/templatetags/icons.py b/proposals/templatetags/icons.py new file mode 100644 index 0000000..551ad49 --- /dev/null +++ b/proposals/templatetags/icons.py | |||
@@ -0,0 +1,14 @@ | |||
1 | from django import template | ||
2 | from django.utils.html import format_html | ||
3 | from django.contrib.admin.templatetags.admin_static import static | ||
4 | |||
5 | |||
6 | register = template.Library() | ||
7 | |||
8 | |||
9 | @register.filter | ||
10 | def boolean_icon(value): | ||
11 | icon_url = static('admin/img/icon-%s.gif' % | ||
12 | {True: 'yes', False: 'no', None: 'unknown'}[value]) | ||
13 | alt_text = {True: 'yes', False: 'no', None: 'pending' }[value] | ||
14 | return format_html('<img src="{0}" alt="{1}" />', icon_url, alt_text) | ||
diff --git a/proposals/tests.py b/proposals/tests.py new file mode 100644 index 0000000..501deb7 --- /dev/null +++ b/proposals/tests.py | |||
@@ -0,0 +1,16 @@ | |||
1 | """ | ||
2 | This file demonstrates writing tests using the unittest module. These will pass | ||
3 | when you run "manage.py test". | ||
4 | |||
5 | Replace this with more appropriate tests for your application. | ||
6 | """ | ||
7 | |||
8 | from django.test import TestCase | ||
9 | |||
10 | |||
11 | class SimpleTest(TestCase): | ||
12 | def test_basic_addition(self): | ||
13 | """ | ||
14 | Tests that 1 + 1 always equals 2. | ||
15 | """ | ||
16 | self.assertEqual(1 + 1, 2) | ||
diff --git a/proposals/urls.py b/proposals/urls.py new file mode 100644 index 0000000..5a33b6f --- /dev/null +++ b/proposals/urls.py | |||
@@ -0,0 +1,9 @@ | |||
1 | from django.conf.urls import patterns, include, url | ||
2 | |||
3 | from proposals.views import ProposalUpdateView, ProposalCreationForm | ||
4 | |||
5 | |||
6 | urlpatterns = patterns('proposals.views', | ||
7 | url(r'(?P<pk>[0-9]+)$', ProposalUpdateView.as_view(), name='update'), | ||
8 | url(r'create/$', ProposalCreationForm.as_view(), name='create'), | ||
9 | ) | ||
diff --git a/proposals/views.py b/proposals/views.py new file mode 100644 index 0000000..aacba55 --- /dev/null +++ b/proposals/views.py | |||
@@ -0,0 +1,30 @@ | |||
1 | from django.shortcuts import resolve_url | ||
2 | from django.views.generic.edit import CreateView, UpdateView | ||
3 | |||
4 | from proposals.models import Proposal | ||
5 | from proposals.forms import UserProposalForm | ||
6 | |||
7 | |||
8 | class ProposalCreationForm(CreateView): | ||
9 | |||
10 | model = Proposal | ||
11 | form_class = UserProposalForm | ||
12 | |||
13 | def get_success_url(self): | ||
14 | return resolve_url("account:profile") | ||
15 | |||
16 | |||
17 | class ProposalUpdateView(UpdateView): | ||
18 | |||
19 | form_class = UserProposalForm | ||
20 | |||
21 | def get_success_url(self): | ||
22 | return resolve_url("account:profile") | ||
23 | |||
24 | def get_queryset(self): | ||
25 | return Proposal.objects.for_user(self.request.user) | ||
26 | |||
27 | def get_context_data(self, **kwargs): | ||
28 | context = super(ProposalUpdateView, self).get_context_data(**kwargs) | ||
29 | context["edit_view"] = True | ||
30 | return context | ||