Получение значения ошибки при попытке просмотра продукта без входа в систему - PullRequest
0 голосов
/ 25 сентября 2019

Создана аналитическая модель для отслеживания пользовательских данных и получения IP-адреса.Но это работает только для вошедшего в систему пользователя.Гость пользователь, когда пытается просмотреть объект, выдает ошибку.

Продукт - views.py

class ProductDetailSlugView(ObjectViewedMixin, DetailView):

    def get_context_data(self, *args, **kwargs):
        context             = super(ProductDetailSlugView, self).get_context_data(*args, **kwargs)
        cart_obj, new_obj   = Cart.objects.new_or_get(self.request)
        context['cart']     = cart_obj

        return context

Аккаунты - views.py

class LoginView(FormView):

        if user is not None:
            login(request, user)
            user_logged_in.send(user.__class__, instance=user, request=request)

            try:
                del request.session['guest_id']
            except:
                pass

Аналитика -mixin.py

from .signals import object_viewed_signal

class ObjectViewedMixin(object):
    def get_context_data(self, *args, **kwargs):
        context = super(ObjectViewedMixin, self).get_context_data(*args, **kwargs)
        request = self.request
        #instance = context['object']
        instance = context.get('object')
        if instance:
            object_viewed_signal.send(instance.__class__, instance=instance, request=request)

        return context

Аналитика - signal.py

from django.dispatch import Signal

object_viewed_signal = Signal(providing_args=['instance', 'request']) 

Аналитика - utils.py

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', None)
    return ip

Аналитика - models.py

def object_viewed_reciver(sender, instance, request, *args, **kwargs):
    _type = ContentType.objects.get_for_model(sender)                                                       # instance.__class__
    print(sender)
    print(instance)
    print(request)
    print(request.user)
    ip_address = None
    try:
        ip_address = get_client_ip(request)
    except:
        pass

    new_view_obj = ObjectViewed.objects.create(
        user = request.user,
        content_type = _type,
        object_id = instance.id,
        ip_address = ip_address                                                                            # TODO: parsing the ip address to get the location
    )

object_viewed_signal.connect(object_viewed_reciver)


class UserSession(models.Model):
    user            = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    ip_address      = models.CharField(max_length=220, blank=True, null=True)
    session_key     = models.CharField(max_length=120, blank=True, null=True)    
    timestamp       = models.DateTimeField(auto_now_add=True)
    active          = models.BooleanField(default=True)
    ended           = models.BooleanField(default=False)

    def end_session(self):
        session_key = self.session_key
        ended = self.ended
        try:
            Session.objects.get(pk=session_key).delete()
            self.active = False
            self.ended = True
            self.save()
        except:
            pass
        return self.ended

def user_logged_in_receiver(sender, instance, request, *args, **kwargs):
    print(instance)
    user = instance
    ip_address = get_client_ip(request)
    session_key = request.session.session_key
    UserSession.objects.create(
        user = user,
        ip_address = ip_address,
        session_key = session_key
    )

user_logged_in.connect(user_logged_in_receiver)

У меня следующий пользователь:

lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 211, in __set__
    self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at 0x7f4975fa09e8>>": "ObjectViewed.user" must be a "User" instance.

    products/views.py in get_context_data

    context = super(ProductDetailSlugView, self).get_context_data(*args, **kwargs)

    analytics/mixin.py  in get_context_data

    object_viewed_signal.send(instance.__class__, instance=instance, request=request) 

1 Ответ

0 голосов
/ 25 сентября 2019

Как показывает ошибка, проблема возникает в сигнале object_viewed_reciver, когда вы пытаетесь создать экземпляр ObjectViewed для текущего пользователя;но модель ожидает экземпляр фактического пользователя.

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

class ObjectViewed(model.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
    ...

, чтобы в вашем сигнале вы могли сделать:

user = request.user if request.user.is_authenticated else None
new_view_obj = ObjectViewed.objects.create(
    user=user,
    content_type=_type,
    object_id=instance.id,
    ip_address=ip_address                                                                                
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...