Ticket #16213: 16213.2.diff

File 16213.2.diff, 6.9 KB (added by Harro, 13 years ago)

Some cleanup

  • django/views/generic/collections.py

     
     1from django.conf.urls.defaults import patterns, url
     2from django.core.exceptions import ImproperlyConfigured
     3from django.db.models import Model
     4from django.db.models.query import QuerySet
     5from django.views import generic
     6
     7class ViewCollection(object):
     8    """
     9        A base class based view collection
     10    """
     11    class_based_views = None
     12    current_app = None
     13
     14    def __init__(self, *args, **kwargs):
     15        """
     16        Constructor.
     17        """
     18        for key, value in kwargs.iteritems():
     19            setattr(self, key, value)
     20
     21    def get_urls(self):
     22        """
     23        Returns the urlspatterns to be used in for the views
     24        """
     25        urlpatterns = patterns('')
     26
     27        for name, regex, cbv in self.class_based_views:
     28            urlpatterns += patterns('',
     29                url(regex, cbv.as_view(), name=name)
     30            )
     31        return urlpatterns
     32
     33    @property
     34    def urls(self):
     35        """
     36        Property to be used in the URLConf in an include method
     37        """
     38        return self.get_urls(), self.current_app
     39
     40    def get_urls_namespacestring(self):
     41        """
     42        Returns the urls prefix we should use for the url reversing
     43        """
     44        if self.current_app is not None:
     45            return '%s:' % self.current_app
     46        return ''
     47
     48
     49class CrudViewCollectionViewMixin(object):
     50    """
     51        A mixin for class based views for the CrudViewCollection
     52    """
     53    extra_context = None
     54    current_app = None
     55
     56    def get_context_data(self, **kwargs):
     57        sup = super(CrudViewCollectionViewMixin, self)
     58        context = {}
     59        if hasattr(sup, 'get_context_data'):
     60            context = sup.get_context_data(**kwargs)
     61        if self.extra_context is not None:
     62            context.update(self.extra_context)
     63        return context
     64
     65    def render_to_response(self, context, **response_kwargs):
     66        """
     67        Returns a response with a template rendered with the given context.
     68        """
     69        if 'current_app' not in response_kwargs:
     70            response_kwargs['current_app'] = self.current_app
     71        return super(CrudViewCollectionViewMixin, self).render_to_response(
     72                context,
     73                **response_kwargs)
     74
     75
     76class CrudListView(CrudViewCollectionViewMixin, generic.ListView):
     77    pass
     78
     79
     80class CrudCreateView(CrudViewCollectionViewMixin, generic.CreateView):
     81    pass
     82
     83
     84class CrudUpdateView(CrudViewCollectionViewMixin, generic.UpdateView):
     85    pass
     86
     87
     88class CrudDeleteView(CrudViewCollectionViewMixin, generic.DeleteView):
     89    pass
     90
     91
     92class CrudDetailView(CrudViewCollectionViewMixin, generic.DetailView):
     93    pass
     94
     95
     96class CrudViewCollection(ViewCollection):
     97    """
     98    A Create, Read (Detail/List), Update, Delete View Collection
     99    """
     100    templates = None
     101    model = None
     102    queryset = None
     103
     104    forms = None
     105    templates = None
     106
     107
     108    def __init__(self, *args, **kwargs):
     109        """
     110        Constructor
     111        """
     112        super(CrudViewCollection, self).__init__(*args, **kwargs)
     113        self.init_views()
     114
     115        #Make sure we have a unique current_app if it is not yet set
     116        if self.current_app is None:
     117            self.current_app = 'crud_%s' % (self.get_model().__class__.lower())
     118
     119
     120    def init_views(self):
     121        """
     122        Initialize the class based views
     123        """
     124        self.class_based_views = [
     125            ('list', r'^$', CrudListView.as_view(
     126                            model = self.get_model(),
     127                            queryset = self.get_queryset(),
     128                            template_name = self.get_template_for('list'),
     129                            current_app = self.current_app
     130            )),
     131            ('create', r'^/create/$', CrudCreateView.as_view(
     132                            model = self.get_model(),
     133                            queryset = self.get_queryset(),
     134                            form_class = self.get_form_for('create'),
     135                            template_name = self.get_template_for('create'),
     136                            current_app = self.current_app
     137            )),
     138            ('update', r'^/update/(?P<pk>\d+)/$', CrudUpdateView.as_view(
     139                            model = self.get_model(),
     140                            queryset = self.get_queryset(),
     141                            form_class = self.get_form_for('update'),
     142                            template_name = self.get_template_for('update'),
     143                            current_app = self.current_app
     144            )),
     145            ('delete', r'^/delete/(?P<pk>\d+)/$', CrudDeleteView.as_view(
     146                            model = self.get_model(),
     147                            queryset = self.get_queryset(),
     148                            template_name = self.get_template_for('delete'),
     149                            success_url = '%s%s' % (
     150                                self.get_urls_namespacestring(),
     151                                'list'
     152                            ),
     153                            current_app = self.current_app,
     154            )),
     155            ('detail', r'^/detail/(?P<pk>\d+)/$', CrudDetailView.as_view(
     156                            model = self.get_model(),
     157                            queryset = self.get_queryset(),
     158                            form_class = self.get_form_for('detail'),
     159                            template_name = self.get_template_for('detail'),
     160                            current_app = self.current_app
     161            ))
     162        ]
     163
     164    def get_template_for(self, view_name):
     165        """
     166        Should return a template path or None
     167        """
     168        if self.templates is None:
     169            self.templates = {}
     170        return self.templates.get(view_name)
     171
     172    def get_form_for(self, view_name):
     173        """
     174        Should return the form object or None
     175        Note: If None the CBV will create a ModelForm
     176        """
     177        if self.forms is None:
     178            self.forms = {}
     179        return self.forms.get(view_name)
     180
     181    def get_model(self):
     182        """
     183        Return the model or get it from the queryset
     184        """
     185        if isinstance(self.model, Model):
     186            return self.model
     187        elif isinstance(self.queryset, QuerySet):
     188            return self.queryset.model
     189        raise ImproperlyConfigured(
     190            'No model or queryset specified on %r' % self.__class__)
     191
     192    def get_queryset(self):
     193        """
     194        Return the queryset or get it from the model
     195        """
     196        if isinstance(self.queryset, QuerySet):
     197            return self.queryset
     198        elif isinstance(self.model, Model):
     199            return self.model.objects.all()
     200        raise ImproperlyConfigured(
     201            'No model or queryset specified on %r' % self.__class__)
Back to Top