Django счётчик просмотров

Govard

Новичок
Пользователь
Апр 21, 2020
22
4
3
models.py

Python:
class News(models.Model):
     title = models.CharField(max_length=150, verbose_name='Наименование')
     content = models.TextField(blank=True, verbose_name='Контент')
     created_ad = models.DateTimeField(auto_now_add=True, verbose_name='Дата публикации')
     updated_at = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
     photo = models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Картинка', blank=True)
     is_published = models.BooleanField(default=True, verbose_name='Опубликовано')
     category = models.ForeignKey('Category', verbose_name='Категория', on_delete=models.PROTECT) # on_delete=models.PROTECT - защита от удаления статей привязанных к категории.
     views = models.IntegerField(default=0)

views.py

Код:
def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            messages.success(request, 'Вы успешно зарегистрировались!')
            return redirect('home')
        else:
            messages.error(request, 'Ошибка регистрации')
    else:
        form = UserRegisterForm()
    return render(request, 'news/register.html', {"form": form})


def user_login(request):
    if request.method == 'POST':
        form = UserLoginForm(data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            return redirect('home')
    else:
        form = UserLoginForm()
    return render(request, 'news/login.html', {"form": form})


def user_logout(request):
    logout(request)
    return redirect('login')


def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            mail = send_mail(form.cleaned_data['subject'], form.cleaned_data['content'], 'web-supsu@yandex.ru', ['kornyukhov94@mail.ru'], fail_silently=True)
            if mail:
                messages.success(request, 'Письмо отправлено!')
                return redirect('contact')
            else:
                messages.error(request, 'Ошибка отправки')
        else:
            messages.error(request, 'Не верно заполнено одно из полей')
    else:
        form = ContactForm()
    return render(request, 'news/test.html', {"form": form})


class HomeNews(ListView):
    model = News
    template_name = 'news/home_news_list.html'
    context_object_name = 'news'
    extra_context = {'title': 'Главная'}
    paginate_by = 5

    def get_queryset(self):
        return News.objects.filter(is_published=True).select_related('category') # .select_related('category') Убирает дублирование SQL запросов.


class NewsByCategory(ListView):
    model = News
    template_name = 'news/home_news_list.html'
    context_object_name = 'news'
    allow_empty = False
    paginate_by = 5

    def get_queryset(self):
        return News.objects.filter(category_id=self.kwargs['category_id'],  is_published=True).select_related('category')


class ViewNews(DetailView):
    model = News
    context_object_name = 'news_item'


class CreateNews(LoginRequiredMixin, CreateView):
    login_url = '/admin/login/' # Перенаправление в админу для авторизации
    form_class = NewsForm
    template_name = 'news/add_news.html'

Шаблон отображения:

Код:
{% extends 'base.html' %}

{% block title %}
{{ news_item.title }}
{% endblock %}

{% block sidebar %}

{% include 'inc/_sidebar.html' %}

{% endblock %}

{% block content %}

<div class="card mb-3">
  <div class="card-header">
    Категория: <a href="{{ news_item.category.get_absolute_url }}">{{ news_item.category }}</a>
    | Просмотры: <span>{{ news_item.views }}</span>
  </div>
  <div class="card-body">
      {% if item.photo %}
      <img src="{{ news_item.photo.url }}" alt="" width="350" class="mr-3">
      {% else %}
      <img src="" alt="" class=" float-left mr-3">
      {% endif %}
        <h5 class="card-title text-center">{{ news_item.title }}</h5>
        <p class="card-text">{{ news_item.content | safe | linebreaks }}</p>
    </div>
  <div class="card-footer text-muted">
    {{ news_item.created_ad|date:"Y-m-d:i:s" }}
  </div>
</div>
{% endblock %}



Здравствуйте. Мне нужно чтобы при каждом заходе на страницу со статьёй, к модели views прибавлялось +1(просмотр). Сейчас только выводится по дефолту 0. Подскажите пожалуйста, как мне сделать так, чтобы при посещении статей счётчик просмотра обновлялся?
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Во вью для статьи добавьте (переопределите) метод get и в нем прибавляйте просмотры при каждом вызове:
Python:
class ViewNews(DetailView):
    model = News
    context_object_name = 'news_item'
    
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.object.views += 1
        self.object.save()
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)
 
  • Мне нравится
Реакции: Govard

Govard

Новичок
Пользователь
Апр 21, 2020
22
4
3
Во вью для статьи добавьте (переопределите) метод get и в нем прибавляйте просмотры при каждом вызове:
Python:
class ViewNews(DetailView):
    model = News
    context_object_name = 'news_item'
   
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        self.object.views += 1
        self.object.save()
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

ОГРОМНЕЙШЕЕ СПАСИБО ВАМ!!! Никто, нигде не хотел помогать кроме вас!!! Безумно благодарю!!!!:love::love::love:
 

Форум IT Специалистов