Как вывести число пользователей, заходивших, просматривающих ту или ниую публикацию в django?

Есть список публикаций 'topic' не моогу понять, как вывести число пользователей, которые просматривали тот или иной topic. Причём не колличество посещений (колличество просмотров я уже вывел), а имменно колличество юзеров. Мой код: models.py class User(AbstractBaseUser, PermissionsMixin):

          username = models.CharField(max_length=255, unique=True)
          first_name = models.CharField(max_length=30, null=True, blank=True)
          last_name = models.CharField(max_length=30, null=True, blank=True)
          email = models.EmailField(max_length=255, unique=True)
          is_staff = models.BooleanField(default=False)
          is_active = models.BooleanField(default=True)
          date_joined = models.DateTimeField(u'date joined', default=timezone.now)
          objects = UserManager()
          avatar = models.ImageField(settings.AUTH_USER_MODEL, 
          default='media/no_image.jpg', blank=True)

          USERNAME_FIELD = 'username'

          REQUIRED_FIELDS = ['email', 'password', 'avatar']

   
    class Topic(models.Model):
          name = models.CharField(max_length=200)
          category = models.ForeignKey(
         Category, verbose_name="Category", on_delete=models.SET_NULL, null=True, 
         related_name='topic'
         )
         content = models.TextField()
         likes = models.ManyToManyField(User, related_name='topic_likes', 
         default=None, blank=True)
         created = models.DateTimeField(auto_now_add=True)
         tags = TaggableManager()
         slug = models.SlugField(max_length=130, unique=True, default=uuid.uuid1)
         author = models.ForeignKey(settings.AUTH_USER_MODEL, 
         on_delete=models.CASCADE)
         user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, 
         related_name='topic_bookmark')
         views = models.ManyToManyField(Ip, related_name="post_views", blank=True)

         objects = models.Manager()

        def total_views(self):
            return self.views.count()

       def __str__(self):
           return self.name


       def d_date(self):
           z = self.created.strptime(str(self.created), '%Y-%m-%d %H:%M:%S.%f+%U:%W')
           r = datetime.datetime.today()
           e = r - z
           return e

      def total_likes(self):
          return self.likes.count()

      def get_absolute_url(self):
         # return reverse("forum:topic_detail", kwargs={"slug": self.url})
           return reverse_lazy('forum:topic_detail', kwargs={'slug': self.slug})

     def tag_list(self) -> str:
         return u", ".join(o.name for o in self.tags.all())



     class Meta:
           verbose_name = 'Topic'
           verbose_name_plural = 'Topics'

Вы можете использовать отношения многие ко многим ресурс Однако если вам это будет лишним то вы можете пойти обходным путём: Создайте новую модель:

models.py

class TopicViews(models.Model):
    IPAddres= models.GenericIPAddressField(default="45.243.82.169")
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)

    class Meta: 
        verbose_name_plural = 'Просмотры Топика'
    
    def __str__(self):
        return self.IPAddres

Также добавьте функцию под вашу модель Topic :

 @property
    def views_count(self):
        return TopicViews.objects.filter(topic=self).count()

Теперь внесите изменения в ваши представления:

views.py

def get_ip(request):
    address=request.META.get('HTTP_X_FORWARDED_FOR')
    if address:
        ip=address.split(',')[0].strip()
    else:
        ip=request.META.get('REMOTE_ADDR')
    return ip    
# Создаст функцию которая будет брать ip запроса

Теперь в detail view укажите следующее: views.py

from .models import Topic, TopicViews

def topic(request, slug):
    ask = get_object_or_404(Topic, slug=slug)
    ip=get_ip(request) # Не забудьте импортировать функцию если она находится в другом месте
    TopicViews.objects.get_or_create(IPAddres=ip, topic=topic)
    return render(request, 'topic.html',{'topic':topic}

Данная функция будет создавать просмотр при обращении к объекту.Так же не будет дублирования просмотров так как завязка под ip выполняется Чтоб вызвать в шаблонах используйте функцию что указали в модели:

topic.html

...
{{ topic.views_count }}
...
Вернуться на верх