Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add crud views with pluggable view mixin

- idea for this is to quickly standup a staff
  admin for announcements and provide your own
  authentication rules via the mixin.
  • Loading branch information...
commit 4546b7e9d5d8ef571e1e93cae5d4f85274b7cb1c 1 parent a5a9200
Patrick Altman authored November 29, 2011
18  announcements/forms.py
... ...
@@ -0,0 +1,18 @@
  1
+from django import forms
  2
+
  3
+from announcements.models import Announcement
  4
+
  5
+
  6
+class AnnouncementForm(forms.ModelForm):
  7
+    
  8
+    class Meta:
  9
+        model = Announcement
  10
+        fields = [
  11
+            "title",
  12
+            "content",
  13
+            "site_wide",
  14
+            "members_only",
  15
+            "dismissal_type",
  16
+            "publish_start",
  17
+            "publish_end"
  18
+        ]
30  announcements/mixins.py
... ...
@@ -0,0 +1,30 @@
  1
+from django.conf import settings
  2
+from django.utils.importlib import import_module
  3
+
  4
+
  5
+def _resolve(mixin_setting):
  6
+    if isinstance(mixin_setting, basestring):
  7
+        try:
  8
+            mod_name, klass_name = mixin_setting.rsplit(".", 1)
  9
+        except ValueError:
  10
+            raise Exception("Improperly configured.")
  11
+        try:
  12
+            mod = import_module(mod_name)
  13
+        except ImportError:
  14
+            raise Exception("Could not import %s" % mod_name)
  15
+        try:
  16
+            klass = getattr(mod, klass_name)
  17
+        except AttributeError:
  18
+            raise Exception("The module '%s' does not contain '%s'." % (mod_name, klass_name))
  19
+        mixin_setting = klass
  20
+    return mixin_setting
  21
+
  22
+
  23
+class DefaultProtectedMixin(object):
  24
+    
  25
+    pass
  26
+
  27
+
  28
+ProtectedMixin = _resolve(
  29
+    getattr(settings, "ANNOUNCEMENTS_PROTECTED_MIXIN", DefaultProtectedMixin)
  30
+)
6  announcements/signals.py
... ...
@@ -0,0 +1,6 @@
  1
+import django.dispatch
  2
+
  3
+
  4
+announcement_created = django.dispatch.Signal(providing_args=["announcement", "request"])
  5
+announcement_updated = django.dispatch.Signal(providing_args=["announcement", "request"])
  6
+announcement_deleted = django.dispatch.Signal(providing_args=["announcement", "request"])
12  announcements/urls.py
... ...
@@ -1,7 +1,15 @@
1 1
 from django.conf.urls.defaults import *
2 2
 
  3
+from announcements.views import detail, dismiss
  4
+from announcements.views import CreateAnnouncementView, UpdateAnnouncementView
  5
+from announcements.views import DeleteAnnouncementView, AnnouncementListView
3 6
 
4 7
 urlpatterns = patterns("",
5  
-    url(r"^(?P<pk>\d+)/$", "announcements.views.detail", name="announcements_detail"),
6  
-    url(r"^(?P<pk>\d+)/hide/$", "announcements.views.dismiss", name="announcement_dismiss")
  8
+    url(r"announcement/(?P<pk>\d+)/$", detail, name="announcements_detail"),
  9
+    url(r"announcement/(?P<pk>\d+)/hide/$", dismiss, name="announcement_dismiss"),
  10
+    
  11
+    url(r"announcement/create/$", CreateAnnouncementView.as_view(), name="announcements_create"),
  12
+    url(r"announcement/(?P<pk>\d+)/update/$", UpdateAnnouncementView.as_view(), name="announcements_update"),
  13
+    url(r"announcement/(?P<pk>\d+)/delete/$", DeleteAnnouncementView.as_view(), name="announcements_delete"),
  14
+    url(r"", AnnouncementListView.as_view(), name="announcements_list"),
7 15
 )
69  announcements/views.py
... ...
@@ -1,8 +1,14 @@
  1
+from django.core.urlresolvers import reverse
1 2
 from django.http import HttpResponse, HttpResponseNotAllowed
2 3
 from django.shortcuts import get_object_or_404
3 4
 from django.template.response import TemplateResponse
  5
+from django.views.generic.edit import CreateView, UpdateView, DeleteView
  6
+from django.views.generic.list import ListView
4 7
 
  8
+from announcements.forms import AnnouncementForm
  9
+from announcements.mixins import ProtectedMixin
5 10
 from announcements.models import Announcement
  11
+from announcements.signals import announcement_created, announcement_updated, announcement_deleted
6 12
 
7 13
 
8 14
 def dismiss(request, pk):
@@ -30,3 +36,66 @@ def detail(request, pk):
30 36
     return TemplateResponse(request, "announcements/detail.html", {
31 37
         "announcement": announcement
32 38
     })
  39
+
  40
+
  41
+class CreateAnnouncementView(CreateView, ProtectedMixin):
  42
+    
  43
+    model = Announcement
  44
+    form_class = AnnouncementForm
  45
+    
  46
+    def form_valid(self, form):
  47
+        self.object = form.save(commit=False)
  48
+        self.object.creator = self.request.user
  49
+        self.object.save()
  50
+        
  51
+        announcement_created.send(
  52
+            sender=self.object,
  53
+            announcement=self.object,
  54
+            request=self.request
  55
+        )
  56
+        return super(CreateAnnouncementView, self).form_valid(form)
  57
+    
  58
+    def get_success_url(self):
  59
+        return reverse("announcements_list")
  60
+
  61
+
  62
+class UpdateAnnouncementView(UpdateView, ProtectedMixin):
  63
+    
  64
+    model = Announcement
  65
+    form_class = AnnouncementForm
  66
+    
  67
+    def form_valid(self, form):
  68
+        response = super(UpdateAnnouncementView, self).form_valid(form)
  69
+        announcement_updated.send(
  70
+            sender=self.object,
  71
+            announcement=self.object,
  72
+            request=self.request
  73
+        )
  74
+        return response
  75
+    
  76
+    def get_success_url(self):
  77
+        return reverse("announcements_list")
  78
+
  79
+
  80
+class DeleteAnnouncementView(DeleteView, ProtectedMixin):
  81
+    
  82
+    model = Announcement
  83
+    
  84
+    def form_valid(self, form):
  85
+        response = super(DeleteAnnouncementView, self).form_valid(form)
  86
+        announcement_deleted.send(
  87
+            sender=self.object,
  88
+            announcement=self.object,
  89
+            request=self.request
  90
+        )
  91
+        return response
  92
+    
  93
+    def get_success_url(self):
  94
+        return reverse("announcements_list")
  95
+
  96
+
  97
+class AnnouncementListView(ListView, ProtectedMixin):
  98
+    
  99
+    model = Announcement
  100
+    queryset = Announcement.objects.all().order_by("-creation_date")
  101
+    paginate_by = 50

0 notes on commit 4546b7e

Please sign in to comment.
Something went wrong with that request. Please try again.