Many blogs and news sites to keep the audience's attention using such methods as ranking popular articles this week, related publications, and some major resources and more advice on user preferences.
First, it was decided to do - it displays a list of popular articles. The first version of the popular articles was based on a general counter views and eventually deduced the article with the most views. This is generally a bad option, since the TOP will result in articles just scored the highest number of views for all time.
Therefore it was necessary to change something. As a result, the output has been introduced popular articles in last 7 days in its simplest form. That is, the table has been added which introduced views of articles by day. Of course, the accuracy of counting under heavy load can vary greatly, but attendance is not reached the 5,000 - 10,000 unique visitors a day - it's not so important.
Now lets proceed with an example of how to make a list of popular articles Django .
Article and Statistics models
Here is a stripped-down version of the model for items, as in this case, I'm interested in only the title of the article.
class Article(models.Model): class Meta: db_table = "article" title = models.CharField('Title', max_length=200) def __str__(self): return self.title
A statistical model views on articles will be the next code.
class ArticleStatistic(models.Model): class Meta: db_table = "ArticleStatistic" article = models.ForeignKey(Article) date = models.DateField('Date', default=timezone.now) views = models.IntegerField('Views', default=0) def __str__(self): return self.article.title class ArticleStatisticAdmin(admin.ModelAdmin): list_display = ('__str__', 'date', 'views') search_fields = ('__str__', )
In this code, made two models:
-
The model itself to collect statistics
Model to display the data in the admin area.
These models will be written in models.py file.
Do not forget to also register the model in the admin in admin.py file.
from django.contrib import admin from .models import Article, ArticleStatistic, ArticleStatisticAdmin admin.site.register(Article) admin.site.register(ArticleStatistic, ArticleStatisticAdmin)
Then do not forget to do a database migration.
python manage.db makemigrations python manage.db migrate
Views
Once we have added to the model, it remains to add the conclusion of popular articles and make the counting statistics when requested article from the server.
from django.views import View from django.shortcuts import render_to_response, get_object_or_404 from django.utils import timezone from django.db.models import Sum # To work with the models of articles I have used knowledge module from knowledge.models import Article, ArticleStatistic # while module is used for displaying articles post # This was done in order to URL items was the following form # /post/42/ - where 42 - it is id od article in database class EArticleView(View): template_name = 'knowledge/article.html' def get(self, request, *args, **kwargs): article = get_object_or_404(Article, id=self.kwargs['article_id']) context = {} # Then we pick up the object of today's statistics, or create a new one if required obj, created = ArticleStatistic.objects.get_or_create( defaults={ "article": article, "date": timezone.now() }, # At the same time define a fence or statistics object creation # by two fields: date and a foreign key to the article date=timezone.now(), article=article ) obj.views += 1 obj.save(update_fields=['views']) # Now pick up the list of the last 5 most popular articles of the week popular = ArticleStatistic.objects.filter( # filter records in the last 7 days date__range=[timezone.now() - timezone.timedelta(7), timezone.now()] ).values( # Taking the field of interest to us, namely, the id and the title # Unfortunately we can not to pick up an object on the foreign key in this case # Only the specific field of the object 'article_id', 'article__title' ).annotate( # Summing over rated recording # All sum properly with matching fields for the requested objects views=Sum('views') ).order_by( # sort the records Descending '-views')[:5] # Take 5 last records context['popular_list'] = popular # We went to the context of the list of articles return render_to_response(template_name=self.template_name, context=context)
Display template
And now just be displayed in page template list of popular articles of the week. I'll note that only give you a template to display a list. This is enough to understand how to get a list of articles on the page.
Do not also forget that I am using django_bootstrap3, therefore, the pattern looks accordingly.
{% if popular_list %}{% load bootstrap3 %} <ul class="list-group"> <li class="list-group-item active"><strong>Популярные публикации за неделю</strong></li> {% for pop_article in popular_list %} <li class="list-group-item"> <a href="{% url 'post:article' pop_article.article_id %}">{{ pop_article.article__title }}</a> </li> {% endfor %} </ul> {% endif %}
URL pattern:
url(r'^(?P<article_id>[0-9]+)/$', views.EArticleView.as_view(), name='article'),
Result
The list of popular articles will be similar to that used on this site, but without the total number of views and, in the admin stats will look like this:
For Django I recommend VDS-server of Timeweb hoster .
Добрый день! В Django я новичок. По Вашей инструкции у меня получилось вывести популярные статьи, но они видны только в статье. Как вывести их на главную страницу? Заранее спасибо за ответ!
Я подумал, что этот вопрос можно рассмотреть немного подробнее, поэтому представил в виде отдельной статьи. Можете посмотреть вариант решения здесь: Вывод списка популярных статей на любой странице сайта
Спасибо Вам большое!!!
Добрый день!
Во-первых перепишите urlpatterns так
Во-вторых вы используете id, а там нужно тогда указать, что это у вас целочисленное значение, по умолчанию обрабатывается как строка. Значит результирующая запись будет такой.
К сожалению это не изменило ситуацию. Убираю ссылку на статью из шаблона и все работает. Вероятно не правильно сформирована ссылка в шаблоне.
Да. действительно, на это я не обратил внимания. Напишите либо так
И этот вариант к сожалению не рабочий =(
Извиняюсь, неправильно написал последний ответ. В рамках данной статьи это не правильно, у вас же во вьюшке формируется объект у которого в post_id должен содержаться его PrimaryKey.
Такая же как и у вас вроди бы.
мда... глупо как-то получилось. У вас же в шаблоне два аргумента задано.
Если делать таким образом, то вьюха отдает id категории а не slug. Попробую пост сделать отдельным приложением. Во всяком случае большое спасибо за помощь.
А. Так вы slug использовали? Тогда там надо брать поле slug из section в запросе.
Вот и я пришел к тому же пути. Так вроди бы логично и красиво выглядит.
Я как понял, этот метод создает статистику каждый день (на каждый день), не удаляя старые данные за день и выводит все данные за сегодняшние просмотры у всех статей?
Да, именно такой и была задумка
спасибо