Вторая сессия ENGINE без срока действия

У меня есть Product модель:


class Product(models.Model):
    title = models.CharField(max_length = 25)
    description = models.TextField(blank = True, null = True)
    price = models.IntegerField(default = 0)

    image = models.ImageField(upload_to = 'products/images', null = True, blank = True)
    image_url = models.URLField(null = True, blank = True)

    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)

    product_views = models.IntegerField(default = 0)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['title']

В каждом представлении пользователя я добавляю по одному в product_views. views.py:

def product_detail_view(request, id):
    if 'views' not in request.session:
        request.session['views'] = []
    arr = request.session['views']

    # obj = Product.objects.get(id = id)
    obj = get_object_or_404(Product, id = id)
    if id not in arr:
        arr.append(id)
        request.session['views'] = arr
        obj.product_views = obj.product_views + 1
        obj.save()

    context = {
        'object': obj,
    }
    return render(request, 'home/detail.html', context)

Я установил SESSION_COOKIE_AGE = 86400 в settings.py. Все работает отлично. Но есть одна проблема. В моем приложении пользователь может войти в систему, а через день ему приходится входить снова. Я хотел добавить флажок Remember me к моему входу, но вот проблема. Я не могу установить определенное время истечения срока действия для конкретного ключа. Поэтому я должен сделать свой собственный 2-й Session Engine. Я написал следующее:

class ProductViews(models.Model):
    product = models.ForeignKey(Product, on_delete = models.CASCADE, related_name = 'views', null = True, blank = True)
    viewer = models.CharField(max_length = 36, null=True, blank=True) # Here, I can take IP if viewer isn't logged in
    user = models.ForeignKey(User, on_delete = models.CASCADE, related_name = 'viewed_products', null = True, blank = True)
    datetime = models.DateTimeField(default = django.utils.timezone.now)

Я могу проверить время истечения срока действия следующим образом:

    dateta = product_v.datetime

    time_now = datetime.datetime.now(dateta.tzinfo)  # current time
    time_now = time_now - timedelta(days = 1)
    if dateta < time_now:  # check if stored time exceeds 1 day
        product_v.delete(keep_parents = True)

Я не знаю, будет ли он работать так же хорошо, как стандартный DB Session Engine. Есть ли у вас какие-нибудь идеи по этому поводу? Я буду благодарен за любую помощь.

Я нашел решение. Нет необходимости делать 2nd Session Engine, потому что это займет много времени, да и редактировать его будет сложно. Вот гораздо более простой способ: В middleware.py я поместил:

class ViewsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        check_view(request)

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response


def check_view(request):
    now = datetime.datetime.today()
    print(request.session['viewed'])
    print(request.session['views'])
    if 'viewed' not in request.session or request.session['viewed'] != now.day:
        request.session['viewed'] = now.day
        request.session['views'] = []

        obj, created = SiteView.objects.get_or_create(
                current = f'{now.year} {now.month} {now.day}',
                defaults = {'current': f'{now.year} {now.month} {now.day}', 'views': 1}
        )
        if not created:
            obj.views += 1
            obj.save()


А в details_view (когда товар просматривается):

def detail_view(request, id):
    obj = get_object_or_404(Product, pub_id = id)
    if 'views' not in request.session:
        request.session['views'] = []
    arr = request.session['views']
    if id not in arr:
        arr.append(id)
        request.session['views'] = arr
        obj.product_views = obj.product_views + 1
        obj.save()

    context = {
        'title' : obj.title,
        'object': obj,
    }
    return render(request, 'shop/products/detail.html', context)

Надеюсь, это понравится вам.

Вернуться на верх