Develop Django blog post reading statistics function

Develop Django blog post reading statistics function

Author: HelloGitHub- Dream figure

The sample code involved in the article has been synchronized to the HelloGitHub-Team repository

How to accurately record the reading volume of an article is a more complicated issue, but for our blog, it is not necessary to record so accurately. Therefore, we use a simple but effective way to record the number of blog posts read: every time an article is viewed, the number of reads +1, which is the so-called PV (Page View) number of the article page. Although simple and rude, it is efficient and practical.

Add new field

In order to record the number of views of an article, a new field for storing the number of views needs to be added to the database table of the article. Therefore, a new model to the blog post viewsfields:


class Post(models.Model):
	# ...  
    #   views  
    views = models.PositiveIntegerField(default=0, editable=False)

Note that viewsthe type field is PositiveIntegerField, only the value of the type 0 or a positive integer, is not possible because the amount of negative reading. Initialization viewsvalue of 0. The editableparameters setFalse be allowed to edit the content of this field through the django admin background. Because the reading volume should be counted based on the number of visits, and should not be modified manually.

Increase model method

Once the user visits an article, then they should be viewsthe value of +1, the process is preferably made Postto complete the model of its own, and therefore give the model to add a custom method:


class Post(models.Model):
	# ...  
    #   views  
    views = models.PositiveIntegerField(default=0)
    # ...  
    def increase_views(self):
        self.views += 1['views'])

increase_viewsFirstly, itself corresponding to viewsa value of +1 fields (the value of the database has not changed at this time), and then call savea method to save the changed value to the database. Note the use of update_fieldsparameters to tell Django only update the database viewsvalue of the field, to improve efficiency.

You may be worried that if two people access an article at the same time, will there be conflicts when changing the value of the reading field in the database? In fact, don t worry, we don t count the number of reading accurately, and the traffic of personal blogs is usually not very large, so the data errors caused by occasional conflicts are negligible.

Migrate the database

Once the model is changed, the database needs to be migrated so that Django will reflect the changes to the database. Run the following two commands in the project root directory:

$ pipenv run python makemigrations
$ pipenv run python migrate

Regarding database migration, you can refer to Django migration and operating database for details .

Modify the view function

When a user requests access to an article, the view function that processes the request is detail. Once the view function is called, indicating that the article has been visited once, so we modify detailthe view function, so that the article be accessed in the amount of reading +1 view function is called.


def detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    #   +1

    md = markdown.Markdown(extensions=[
        #   TocExtension   slugify
    post.body = md.convert(post.body)

    m ='<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S)
    post.toc = if m is not None else ''

    return render(request, 'blog/detail.html', context={'post': post})

That simply call the model in the view function increase_viewsmethod can be.

Display reading volume in the template

Displaying the reading volume in the template is the same as displaying other fields, just use the template variable. That is, the {{ post.views }} template variables are used where appropriate in the template. Here we modify two places respectively, index.html and detail.html.


<div class="entry-meta">
  <span class="views-count"><a href="{{ post.get_absolute_url }}">{{ post.views }}  </a></span>

<div class="entry-meta">
  <span class="views-count"><a href="#">{{ post.views }}  </a></span>

Well, so that every time a user visits the article details, the viewsrecorded value will be +1, so as to achieve the purpose of roughly counting the reading volume.

"Explain the open source project series" -Let people who are interested in open source projects no longer be afraid, and let the initiators of open source projects no longer be alone. Follow our article, you will find the fun of programming, use and discover how easy it is to participate in open source projects. Welcome to leave a message to contact us, join us, let more people fall in love with open source, contribute to open source~