📜 ⬆️ ⬇️

Some details about Class Based View, part 1

Introduction

Hello, dear readers! For many django developers, it is no secret that from version 1.3+ instead of the generic views used earlier, we need to start using class based views. And with a 1.4+ version, generic views can generally become deprecated. Information about class based views (hereinafter CBV) on the Internet is quite stingy (and even more so in runet). No, of course there are excellent articles, including here on Habré. One of the articles was published just the other day. But I belong to the category of people that are used to learn everything in practice and this topic is written for the same people.
As a practical task, I chose the classic option - creating a blog. In order to use the features of CBV to the maximum, we complicate the task a little. Let it be not just a blog, but a blog, with the ability to publish private articles that are not accessible to unauthorized users.
Further reasoning implies that the reader is familiar with the Django framework and has the skills to create projects.


Part 1 , Part 2 , Part 3 , Part 4

Actually, we will start with this - with the creation of a new project. Hmm ... Let the project be called habratest.
')
Work with the project

I leave the creation of templates and setting up the project on your shoulders, the article is not about that. I immediately go to our models and displays. To begin with we will be defined with structure of models Here is what version I stopped at:

# coding: utf-8 # author: damirazo from django.contrib.auth.models import User from django.db import models from django.contrib import admin class Post(models.Model): author = models.ForeignKey(to=User, verbose_name=u'') name = models.CharField(max_length=128, verbose_name=u'') text = models.TextField(verbose_name=u'') created_at = models.DateTimeField(auto_now_add=True, verbose_name=u' ') rating = models.IntegerField(default=0, verbose_name=u'') is_private = models.BooleanField(default=False, verbose_name=u' ?') is_delete = models.BooleanField(default=False, verbose_name=u' ?') def __unicode__(self): return self.name class Meta(object): db_table = 'habraposts' ordering = ['-created_at',] class PostAdmin(admin.ModelAdmin): list_display = ('name', 'author', 'created_at') admin.site.register(Post, PostAdmin) 


Actually the purpose of each of the fields is already clear from the attribute verbose_name, so I will not linger here.
Next, you need to proceed to the most important of the points - the creation of mappings, which we implement through CBV. Our views.py will look like this:

 # coding: utf-8 # author: damirazo from django.views.generic import ListView from models import Post class Posts(ListView): """     """ #          as_view() # url(r'^$', Posts.as_view(context_object_name='posts', template_name='posts.html)) model = Post #           context_object_name = 'posts' #   template_name = 'posts.html' #    1  paginate_by = 10 def get_queryset(self): qs = Post.objects.filter(is_delete=False).order_by('-created_at') if not self.request.user.is_authenticated(): return qs.exclude(is_private=True) return qs class PostsIndex(Posts): """      """ template_name = 'index.html' def get_queryset(self): return super(PostsIndex, self).get_queryset().exclude(rating__lt=10) 


Here, despite the comments in the code, I’ll go into details.
The Posts class is inherited directly from ListView, which supports paginated lists. We override the get_queryset method, in which we check whether the user is authorized on the site. For unauthorized users (guests), we exclude from the initial queryset all objects whose is_private attribute value equals True.
The next class used in this example is called PostsIndex. It will be used to display articles on the main page. By analogy with Habr, there will be displayed articles that have a rating equal to or greater than 10. In this class, we again override the get_queryset method. This time, we also exclude articles whose rating is less than 10 from the Queryset object (our list of articles). So, as the Queryset object for users and unauthorized users was filtered in the parent class Posts, then in the PostIndex class we immediately get an object accessible to this user ( or guest). Therefore, one of the main advantages of CBV is the ability to use all OOP tools when working with maps.
It only remains for us to consider what the routes in our project will look like:

 #   ,          #       (  ,  , 10) url(r'^$', PostsIndex.as_view()), url(r'^page(?P<page>\d+)/$', PostsIndex.as_view()), #     url(r'^posts/$', Posts.as_view()), url(r'^posts/page(?P<page>\d+)/$', Posts.as_view()) 


Actually at this point you can finish the first stage. If this format of articles interest users, then I will publish a series of articles. Next you should expect to see the details of the individual object (for example, viewing the article). Then I plan to publish articles on working with forms (publishing an article, editing an article).

PS If you find errors or inaccuracies in the article, then welcome to private messages or comments. I will also be very happy with the advice of professionals who can dot the “i” and tell about my mistakes.

I wish all the best weekend and good luck :).

UPD. Updated the example in the article (thanks to the user marazmiki ). And also laid out a test project that includes this example. Do not forget to edit the file settings.py to fit your needs. The project can be found here . If you find any errors or omissions, please inform.

Source: https://habr.com/ru/post/137168/


All Articles