Django | Как реализовать счетчик просмотров БЕЗ НАКРУТКИ!
Как реализовать счетчик просмотров при этом исключая возможность НАКРУТКИ (простые варианты аля counter +=1 не канает) через reload браузера.
class Post(models.Model):
...
total_views = models.IntegerField(default=0)
def counter(self):
return self.total_views += 1
Ответы (1 шт):
Я все таки разобрался, и хотел бы чтобы люди которые столкнулись с такой проблемой получили решение.
В файле models.py:
from django.db import models
class Ip(models.Model): # наша таблица где будут айпи адреса
ip = models.CharField(max_length=100)
def __str__(self):
return self.ip
class Post(models.Model): # модель у которой будем считать просмотры
...
views = models.ManyToManyField(Ip, related_name="post_views", blank=True)
Регистрируем модели в админке admin.py:
from django.contrib import admin
from .models import Post, Ip
admin.site.register(Post)
admin.site.register(Ip)
В файле views.py создаем метод получения айпи пользователя и наши вьюшки:
from django.shortcuts import render
from videos.models import Post, Ip
# Метод для получения айпи
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR') # В REMOTE_ADDR значение айпи пользователя
return ip
# Главная страница тут рендерим все посты
def home_view(request):
posts = Post.objects.all()
context = {
'posts' : posts,
}
return render(request, 'main/home.html', context)
# Страница самого поста
def post_view(request, slug):
post = Post.objects.get(slug=slug)
ip = get_client_ip(request)
if Ip.objects.filter(ip=ip).exists():
post.views.add(Ip.objects.get(ip=ip))
else:
Ip.objects.create(ip=ip)
post.views.add(Ip.objects.get(ip=ip))
context = {
'post' : post,
}
return render(request, 'main/post.html', context)
Мой файл urls.py:
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from .views import (
home_view,
post_view,
)
urlpatterns = [
path('admin/', admin.site.urls),
path('', home_view, name='home-view'),
path('posts/<str:slug>/', post_view, name='post'),
]
Для того чтобы получить количество просмотров в файле models.py в модели Post создаем метод который будет нам возвращать кол-во просмотров:
def total_views(self):
return self.views.count()
Шаблон main/home.html:
{% extends 'base.html' %}
{% block content %}
<div class="content">
<div class="grid-container">
{% for post in posts %}
<div class="item">
<a href="/posts/{{post.slug}}/">
<p>{{post.title}}<p>
<p>Просмотры : {{post.total_views}}</p> <!-- Просмотры -->
</a>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
Шаблон main/post.html:
{% extends 'base.html' %}
{% block content %}
<div class="post">
<h3>{{post.title}}</h3>
<hr>
<p>Просмотры : {{post.total_views}}</p> <!-- Просмотры -->
<hr>
<p>Описание: {{post.desc}}</p>
</div>
{% endblock content %}
Так-то так, надеюсь что если у кого-то возникнет такой вопрос, он наткнется на мое решение и оно ему поможет. Спасибо за внимание!