问题描述
我正在尝试更新配置文件模型,以扩展默认的用户模型。但是,由于Profile不显示任何条目,因此明显存在问题。您能否建议如何在扩展了另一个中间件的中间件中正确更新模型?
models.py
class Profile(models.Model):
user = models.OnetoOneField(User,on_delete=models.CASCADE)
last_activity = models.DateTimeField() # filled in by middleware
def __str__(self):
return str(self.id)
serializers.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
view.py
class ProfileList(ListAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
middleware.py
from django.utils import timezone
class UpdateLastActivityMiddleware(object):
def __init__(self,get_response):
self.get_response = get_response
def __call__(self,request):
return self.get_response(request)
def process_view(self,request,view_func,view_args,view_kwargs):
if request.user.is_authenticated():
# Update last visit time after request finished processing.
# I'm trying to create record - in case user had no activity before
Profile.objects.filter(user__id=request.user.pk).update_or_create(last_activity=timezone.Now()) # <-- looks like something is off here,since I'm not sure how to correctly update extended model
settings.py
MIDDLEWARE = [
...
'core.middleware.UpdateLastActivityMiddleware',]
解决方法
numbers = [1,2,1,4,1]
count=0
for i in numbers :
count=count+1
if i == 1:
a=[]
a.append(count-1)
print(a) #5
使用
Profile.objects.filter(user__id=request.user.pk).update_or_create(last_activity=timezone.now())
原因是由于这是一对一的关系,因此您不需要user.profile.last_activity=timezone.now()
user.save()
,因为用户将始终拥有个人资料,反向关系应该可以立即使用,并且您可以进行更新属性update_or_create
直接。
由于@Borko Kovacev和大量的Google搜索,这就是我最终得到的解决方案:
middleware.py
class UpdateLastActivityMiddleware:
def __init__(self,get_response):
self.get_response = get_response
def __call__(self,request):
return self.get_response(request)
def process_view(self,request,view_func,view_args,view_kwargs):
assert hasattr(request,'user')
# need to separately detect user when used middleware with JWT (else Anonymous User)
try:
auth_res = authentication.JWTAuthentication().authenticate(request)
except InvalidToken:
return JsonResponse({'error': 'Invalid token'},status=status.HTTP_401_UNAUTHORIZED)
if auth_res:
request.user = auth_res[0]
# save last_activity on each authenticated request
if request.user.is_authenticated:
request.user.profile.last_activity = timezone.now() # assigning last_activity
request.user.save() # this triggers signal on User model saving
print(f'MIDDLEWARE saved last_activity for {request.user}')
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import Profile
@receiver(post_save,sender=User) # to populate Profile on user creation (else fails because Profile record does not exist for user)
def create_profile(sender,instance,created,**kwargs):
if created:
print('signals create_profile ')
Profile.objects.create(user=instance)
@receiver(post_save,sender=User) # to update Profile on user update (triggered by middleware)
def save_profile(sender,**kwargs):
print('signals save_profile ')
instance.profile.save()