forked from rc/aircox
		
	work on postlistsection, rework on routes
This commit is contained in:
		
							
								
								
									
										140
									
								
								cms/routes.py
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								cms/routes.py
									
									
									
									
									
								
							@ -12,14 +12,14 @@ class Router:
 | 
			
		||||
            self.registry.append(route)
 | 
			
		||||
 | 
			
		||||
    def register_set (self, view_set):
 | 
			
		||||
        for route in view_set.routes:
 | 
			
		||||
            self.register(route)
 | 
			
		||||
        for url in view_set.urls:
 | 
			
		||||
            self.register(url)
 | 
			
		||||
 | 
			
		||||
    def unregister (self, route):
 | 
			
		||||
        self.registry.remove(route)
 | 
			
		||||
 | 
			
		||||
    def get_urlpatterns (self):
 | 
			
		||||
        return [ route.get_url() for route in self.registry ]
 | 
			
		||||
        return [ url for url in self.registry ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Route:
 | 
			
		||||
@ -33,125 +33,113 @@ class Route:
 | 
			
		||||
 | 
			
		||||
    The given view is considered as a django class view, and has view_
 | 
			
		||||
    """
 | 
			
		||||
    model = None        # model routed here
 | 
			
		||||
    view = None         # view class to call
 | 
			
		||||
    view_kwargs  = None   # arguments passed to view at creation of the urls
 | 
			
		||||
    name = None         # route name
 | 
			
		||||
    url_args = []       # arguments passed from the url [ (name : regex),... ]
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = None         # route name
 | 
			
		||||
        is_list = False     # route is for a list
 | 
			
		||||
        url_args = []       # arguments passed from the url [ (name : regex),... ]
 | 
			
		||||
 | 
			
		||||
    def __init__ (self, model, view, view_kwargs = None):
 | 
			
		||||
        self.model = model
 | 
			
		||||
        self.view = view
 | 
			
		||||
        self.view_kwargs = view_kwargs
 | 
			
		||||
        self.embed = False
 | 
			
		||||
 | 
			
		||||
        _meta = {}
 | 
			
		||||
        _meta.update(Route.Meta.__dict__)
 | 
			
		||||
        _meta.update(self.Meta.__dict__)
 | 
			
		||||
        self._meta = _meta
 | 
			
		||||
 | 
			
		||||
        self.base_name = model._meta.verbose_name_plural.lower()
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, request, **kwargs):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset (cl, model, request, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Called by the view to get the queryset when it is needed
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get (self, request, **kwargs):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_object (cl, model, request, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        Called by the view to get the object when it is needed
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_url (self):
 | 
			
		||||
        pattern = '^{}/{}'.format(self.base_name, self.Meta.name)
 | 
			
		||||
        if self._meta['url_args']:
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_title (cl, model, request, **kwargs):
 | 
			
		||||
        return ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def as_url (cl, model, view, view_kwargs = None):
 | 
			
		||||
        base_name = model._meta.verbose_name_plural.lower()
 | 
			
		||||
 | 
			
		||||
        pattern = '^{}/{}'.format(base_name, cl.name)
 | 
			
		||||
        if cl.url_args:
 | 
			
		||||
            url_args = '/'.join([
 | 
			
		||||
                '(?P<{}>{}){}'.format(
 | 
			
		||||
                    arg, expr,
 | 
			
		||||
                    (optional and optional[0] and '?') or ''
 | 
			
		||||
                )
 | 
			
		||||
                for arg, expr, *optional in self._meta['url_args']
 | 
			
		||||
                for arg, expr, *optional in cl.url_args
 | 
			
		||||
            ])
 | 
			
		||||
            pattern += '/' + url_args
 | 
			
		||||
        pattern += '/?$'
 | 
			
		||||
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'route': self,
 | 
			
		||||
            'route': cl,
 | 
			
		||||
        }
 | 
			
		||||
        if self.view_kwargs:
 | 
			
		||||
            kwargs.update(self.view_kwargs)
 | 
			
		||||
        if view_kwargs:
 | 
			
		||||
            kwargs.update(view_kwargs)
 | 
			
		||||
 | 
			
		||||
        return url(pattern, self.view, kwargs = kwargs,
 | 
			
		||||
                   name = self.base_name + '_' + self.Meta.name)
 | 
			
		||||
        return url(pattern, view, kwargs = kwargs,
 | 
			
		||||
                   name = base_name + '_' + cl.name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DetailRoute (Route):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = 'detail'
 | 
			
		||||
        is_list = False
 | 
			
		||||
        url_args = [
 | 
			
		||||
            ('pk', '[0-9]+'),
 | 
			
		||||
            ('slug', '(\w|-|_)+', True),
 | 
			
		||||
        ]
 | 
			
		||||
    name = 'detail'
 | 
			
		||||
    url_args = [
 | 
			
		||||
        ('pk', '[0-9]+'),
 | 
			
		||||
        ('slug', '(\w|-|_)+', True),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get (self, request, **kwargs):
 | 
			
		||||
        return self.model.objects.get(pk = int(kwargs['pk']))
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_object (cl, model, request, pk, **kwargs):
 | 
			
		||||
        return model.objects.get(pk = int(pk))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AllRoute (Route):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = 'all'
 | 
			
		||||
        is_list = True
 | 
			
		||||
    name = 'all'
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, request, **kwargs):
 | 
			
		||||
        return self.model.objects.all()
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset (cl, model, request, **kwargs):
 | 
			
		||||
        return model.objects.all()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ThreadRoute (Route):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = 'thread'
 | 
			
		||||
        is_list = True
 | 
			
		||||
        url_args = [
 | 
			
		||||
            ('pk', '[0-9]+'),
 | 
			
		||||
        ]
 | 
			
		||||
    name = 'thread'
 | 
			
		||||
    url_args = [
 | 
			
		||||
        ('pk', '[0-9]+'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, request, **kwargs):
 | 
			
		||||
        return self.model.objects.filter(thread__pk = int(kwargs['pk']))
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset (cl, model, request, pk, **kwargs):
 | 
			
		||||
        return model.objects.filter(thread__pk = int(pk))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DateRoute (Route):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = 'date'
 | 
			
		||||
        is_list = True
 | 
			
		||||
        url_args = [
 | 
			
		||||
            ('year', '[0-9]{4}'),
 | 
			
		||||
            ('month', '[0-9]{2}'),
 | 
			
		||||
            ('day', '[0-9]{1,2}'),
 | 
			
		||||
        ]
 | 
			
		||||
    name = 'date'
 | 
			
		||||
    url_args = [
 | 
			
		||||
        ('year', '[0-9]{4}'),
 | 
			
		||||
        ('month', '[0-9]{2}'),
 | 
			
		||||
        ('day', '[0-9]{1,2}'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, request, **kwargs):
 | 
			
		||||
        return self.model.objects.filter(
 | 
			
		||||
            date__year = int(kwargs['year']),
 | 
			
		||||
            date__month = int(kwargs['month']),
 | 
			
		||||
            date__day = int(kwargs['day']),
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset (cl, model, request, year, month, day, **kwargs):
 | 
			
		||||
        return model.objects.filter(
 | 
			
		||||
            date__year = int(year),
 | 
			
		||||
            date__month = int(month),
 | 
			
		||||
            date__day = int(day),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SearchRoute (Route):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        name = 'search'
 | 
			
		||||
        is_list = True
 | 
			
		||||
    name = 'search'
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self, request, **kwargs):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_queryset (cl, model, request, **kwargs):
 | 
			
		||||
        q = request.GET.get('q') or ''
 | 
			
		||||
        qs = self.model.objects
 | 
			
		||||
        qs = model.objects
 | 
			
		||||
        for search_field in model.search_fields or []:
 | 
			
		||||
            r = self.model.objects.filter(**{ search_field + '__icontains': q })
 | 
			
		||||
            r = model.objects.filter(**{ search_field + '__icontains': q })
 | 
			
		||||
            if qs: qs = qs | r
 | 
			
		||||
            else: qs = r
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										166
									
								
								cms/views.py
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								cms/views.py
									
									
									
									
									
								
							@ -8,63 +8,6 @@ from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
import cms.routes as routes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Section (DetailView):
 | 
			
		||||
    """
 | 
			
		||||
    Base class for sections. Sections are view that can be used in detail view
 | 
			
		||||
    in order to have extra content about a post.
 | 
			
		||||
    """
 | 
			
		||||
    template_name = 'cms/section.html'
 | 
			
		||||
    classes = ''
 | 
			
		||||
    title = ''
 | 
			
		||||
    content = ''
 | 
			
		||||
    header = ''
 | 
			
		||||
    bottom = ''
 | 
			
		||||
 | 
			
		||||
    def get_context_data (self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context.update({
 | 
			
		||||
            'title': self.title,
 | 
			
		||||
            'header': self.header,
 | 
			
		||||
            'content': self.content,
 | 
			
		||||
            'bottom': self.bottom,
 | 
			
		||||
            'classes': self.classes,
 | 
			
		||||
        })
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def get (self, parent, request, object = None, **kwargs):
 | 
			
		||||
        print(type(object))
 | 
			
		||||
        self.object = object
 | 
			
		||||
        context = self.get_context_data(**kwargs)
 | 
			
		||||
        return render_to_string(self.template_name, context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListSection (Section):
 | 
			
		||||
    """
 | 
			
		||||
    Section to render list. The context item 'object_list' is used as list of
 | 
			
		||||
    items to render.
 | 
			
		||||
    """
 | 
			
		||||
    class Item:
 | 
			
		||||
        icon = None
 | 
			
		||||
        title = None
 | 
			
		||||
        text = None
 | 
			
		||||
 | 
			
		||||
        def __init__ (self, icon, title = None, text = None):
 | 
			
		||||
            self.icon = icon
 | 
			
		||||
            self.title = title
 | 
			
		||||
            self.text = text
 | 
			
		||||
 | 
			
		||||
    template_name = 'cms/section_list.html'
 | 
			
		||||
 | 
			
		||||
    def get_object_list (self):
 | 
			
		||||
        return []
 | 
			
		||||
 | 
			
		||||
    def get_context_data (self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context['classes'] += ' section_list'
 | 
			
		||||
        context['object_list'] = self.get_object_list()
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PostListView (ListView):
 | 
			
		||||
    """
 | 
			
		||||
    List view for posts and children
 | 
			
		||||
@ -94,6 +37,9 @@ class PostListView (ListView):
 | 
			
		||||
 | 
			
		||||
    model = None
 | 
			
		||||
    query = None
 | 
			
		||||
    classes = ''
 | 
			
		||||
    title = ''
 | 
			
		||||
    embed = False
 | 
			
		||||
    fields = [ 'date', 'time', 'image', 'title', 'content' ]
 | 
			
		||||
 | 
			
		||||
    def __init__ (self, *args, **kwargs):
 | 
			
		||||
@ -101,30 +47,45 @@ class PostListView (ListView):
 | 
			
		||||
        if self.query:
 | 
			
		||||
            self.query = Query(self.query)
 | 
			
		||||
 | 
			
		||||
    def dispatch (self, request, *args, **kwargs):
 | 
			
		||||
        self.route = self.kwargs.get('route')
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_queryset (self):
 | 
			
		||||
        route = self.kwargs['route']
 | 
			
		||||
        qs = route.get_queryset(self.request, **self.kwargs)
 | 
			
		||||
        qs = self.route.get_queryset(self.model, self.request, **self.kwargs)
 | 
			
		||||
        qs = qs.filter(public = True)
 | 
			
		||||
 | 
			
		||||
        query = self.query or PostListView.Query(self.request.GET)
 | 
			
		||||
        if query.exclude:
 | 
			
		||||
            qs = qs.exclude(id = int(exclude))
 | 
			
		||||
 | 
			
		||||
        if query.embed:
 | 
			
		||||
            self.embed = True
 | 
			
		||||
 | 
			
		||||
        if query.order == 'asc':
 | 
			
		||||
            qs.order_by('date', 'id')
 | 
			
		||||
        else:
 | 
			
		||||
            qs.order_by('-date', '-id')
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_context_data (self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context.update({
 | 
			
		||||
            'list': self
 | 
			
		||||
            'list': self,
 | 
			
		||||
            'title': self.get_title(),
 | 
			
		||||
            'classes': self.classes,
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def get_title (self):
 | 
			
		||||
        if self.title:
 | 
			
		||||
            return self.title
 | 
			
		||||
 | 
			
		||||
        title = self.route and self.route.get_title(self.model, self.request,
 | 
			
		||||
                                                    **self.kwargs)
 | 
			
		||||
        return title
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PostDetailView (DetailView):
 | 
			
		||||
    """
 | 
			
		||||
@ -153,7 +114,7 @@ class PostDetailView (DetailView):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context.update({
 | 
			
		||||
            'sections': [
 | 
			
		||||
                section.get(self, self.request, object = self.object)
 | 
			
		||||
                section.get(self.request, object = self.object)
 | 
			
		||||
                    for section in self.sections
 | 
			
		||||
            ]
 | 
			
		||||
        })
 | 
			
		||||
@ -186,8 +147,85 @@ class ViewSet:
 | 
			
		||||
            model = self.model
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.routes = [ route(self.model, self.list_view)
 | 
			
		||||
        self.urls = [ route.as_url(self.model, self.list_view)
 | 
			
		||||
                            for route in self.list_routes ] + \
 | 
			
		||||
                      [ routes.DetailRoute(self.model, self.detail_view ) ]
 | 
			
		||||
                      [ routes.DetailRoute.as_url(self.model, self.detail_view ) ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Section (DetailView):
 | 
			
		||||
    """
 | 
			
		||||
    Base class for sections. Sections are view that can be used in detail view
 | 
			
		||||
    in order to have extra content about a post.
 | 
			
		||||
    """
 | 
			
		||||
    template_name = 'cms/section.html'
 | 
			
		||||
    classes = ''
 | 
			
		||||
    title = ''
 | 
			
		||||
    content = ''
 | 
			
		||||
    header = ''
 | 
			
		||||
    bottom = ''
 | 
			
		||||
 | 
			
		||||
    def get_context_data (self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context.update({
 | 
			
		||||
            'title': self.title,
 | 
			
		||||
            'header': self.header,
 | 
			
		||||
            'content': self.content,
 | 
			
		||||
            'bottom': self.bottom,
 | 
			
		||||
            'classes': self.classes,
 | 
			
		||||
        })
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def get (self, request, **kwargs):
 | 
			
		||||
        self.object = kwargs.get('object')
 | 
			
		||||
        context = self.get_context_data(**kwargs)
 | 
			
		||||
        return render_to_string(self.template_name, context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListSection (Section):
 | 
			
		||||
    """
 | 
			
		||||
    Section to render list. The context item 'object_list' is used as list of
 | 
			
		||||
    items to render.
 | 
			
		||||
    """
 | 
			
		||||
    class Item:
 | 
			
		||||
        icon = None
 | 
			
		||||
        title = None
 | 
			
		||||
        text = None
 | 
			
		||||
 | 
			
		||||
        def __init__ (self, icon, title = None, text = None):
 | 
			
		||||
            self.icon = icon
 | 
			
		||||
            self.title = title
 | 
			
		||||
            self.text = text
 | 
			
		||||
 | 
			
		||||
    template_name = 'cms/section_list.html'
 | 
			
		||||
 | 
			
		||||
    def get_object_list (self):
 | 
			
		||||
        return []
 | 
			
		||||
 | 
			
		||||
    def get_context_data (self, **kwargs):
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context['classes'] += ' section_list'
 | 
			
		||||
        context['object_list'] = self.get_object_list()
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PostListSection (PostListView):
 | 
			
		||||
    route = None
 | 
			
		||||
    model = None
 | 
			
		||||
    embed = True
 | 
			
		||||
 | 
			
		||||
    def __init__ (self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def get_kwargs (self, request, **kwargs):
 | 
			
		||||
        return kwargs
 | 
			
		||||
 | 
			
		||||
    def dispatch (self, request, *args, **kwargs):
 | 
			
		||||
        kwargs = self.get_kwargs(kwargs)
 | 
			
		||||
        # TODO: to_string
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
# TODO:
 | 
			
		||||
# - get_title: pass object / queryset
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user