python - 尝试在未登录的情况下查看产品时出现值错误
问题描述
创建了一个分析模型来跟踪用户数据并获取 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
分析-signals.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)
解决方案
如错误所示,问题发生在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
)
推荐阅读
- javascript - 通过 AJAX 提高加载时间?
- memory-management - what is the garbage collection logic in Survivor memory. - Is this based on the time which objects are created or based on usage freequency
- javascript - Javascript - Find Value of Item in Array by Knowing Index
- ios - Swift vs Objective C pointer manipulation issue
- swift - Would I run into any problems with having protocols with shared requirements?
- mongodb - MongoDB 上的键名长度有限制吗?
- ios - 为什么 iPad 不能渲染“离线”情节而 iPhone 可以?
- reactjs - React - How to replace the hover color of an Ant-Design Primary button with a css variable?
- azure-devops - 如何在 Azure DevOps 中重命名标签
- android - Android studio - 错误:找不到符号变量项