Как увеличить количество посещений только при первом обращении пользователя к странице? - PullRequest
1 голос
/ 15 марта 2019

Я хочу сделать следующее: каждый раз, когда пользователь входит в статью, он увеличивает посещение на +1, но только при первом входе пользователя в систему, поэтому я должен сохранить тот факт, что пользователь уже вошел встраница в каком-то месте.Но я не использую аутентификацию или что-то подобное.

Я знаю, что могу использовать javascript для хранения в LocalStorage, но я все еще не знаю, как работать с APIS в серверной части.

Какой самый простой способ сделать это на бэкэнде?

В настоящее время функция, которая увеличивает это, как показано ниже.ПРИМЕЧАНИЕ: я создаю новый объект вместо того, чтобы использовать что-то вроде «instance.visits + = 1», потому что мне нужно сохранять дату каждого посещения, чтобы отфильтровать сообщения с большим количеством посещений за определенный период времени, и это был единственный способЯ понял.

class ArticlePage(Page):
    # ....

    def serve(self, request, *args, **kwargs):
        request.is_preview = getattr(request, 'is_preview', False)

        self.views.create(date=datetime.datetime.now())
        self.save()
        print(self.views.all().count())

        return TemplateResponse(
            request,
            self.get_template(request, *args, **kwargs),
            self.get_context(request, *args, **kwargs)
        )

class ArticlePageViews(models.Model):
    article = models.ForeignKey(
        ArticlePage,
        on_delete=models.CASCADE,
        related_name='views'
    )
    date = models.DateTimeField()

    def __str__(self):
        return f'{self.date}'

Ответы [ 2 ]

1 голос
/ 16 марта 2019

Поскольку вам нужно только одно представление для каждого пользователя, вы не можете сохранять представления в пользовательском сеансе, поскольку сеанс меняется при входе пользователя в систему. Я бы предложил вам установить файл cookie UUID при первом посещении пользователем вашего сайта. и установить длительный срок годности, например, 10 лет. Это можно сделать с помощью промежуточного программного обеспечения:

# middleware.py
import uuid


class UUIDMiddleware:
    """
    Middleware to set a UUID cookie when a user visits
    for the first time.
    """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if not request.COOKIES.get('user_uuid'):
            user_uuid = str(uuid.uuid4())
            # set cookie in request so it can be used on the first visit
            request.COOKIES['user_uuid'] = user_uuid

            response = self.get_response(request)

            max_age = 60 * 60 * 24 * 365 * 10  # 10 years
            response.set_cookie('user_uuid',  user_uuid, max_age=max_age)
            return response

        return self.get_response(request)

Не забудьте добавить ваше промежуточное ПО в настройки. Теперь в вашей модели ArticlePageViews вы можете установить ограничение unique_together:

class ArticlePageViews(models.Model):
    article = models.ForeignKey(
        ArticlePage,
        on_delete=models.CASCADE,
        related_name='views'
    )
    user_uuid = models.UUIDField()
    date = models.DateTimeField(auto_now_add=True)  # set datetime automatically

    class Meta:
        unique_together = ('article', 'user_uuid')

    def __str__(self):
        return f'{self.date}'

и, на ваш взгляд (только пример):

def article_view(request, article_id):
     article = get_object_or_404(ArticlePage, pk=article_id)
     user_uuid = request.COOKIES.get('uuid_cookie')
     if user_uuid is not None:  # user_uuid may not be set yet
         try:
             ArticlePageViews.objects.create(article=artricle, user_uuid=user_uuid)
         except IntegrityError:
             #  unique_together validation failed, so the user already viewed this article
             pass  # don't do anything
     ...
1 голос
/ 15 марта 2019

Вот возможность использования кофточек

class ArticlePage(Page):
    # ....

    def serve(self, request, *args, **kwargs):
        request.is_preview = getattr(request, 'is_preview', False)
        if not 'cookie_name' in request.COOKIES:
          self.views.create(date=datetime.datetime.now())
          self.save()
        print(self.views.all().count())

        response=TemplateResponse(
            request,
            self.get_template(request, *args, **kwargs),
            self.get_context(request, *args, **kwargs)
        )
        response.set_cookie('cookie_name', 'cookie_value')
        return response

см. это , чтобы установить время истечения для Куки

...