Django中如何结合@setter与Auth Token正确设置Post的userkey?
问题解决:NOT NULL约束失败与用户关联问题
错误原因
你的@user.setter实现完全不符合要求:它没有接收要设置的用户对象参数,反而返回了一个ForeignKey字段定义,导致调用serializer.save(user=self.request.user)时,根本没有将用户赋值到userkey字段,数据库因userkey_id不为空的约束抛出错误。
两种修正方案
方案一:直接操作关联字段(最简方式)
不需要保留错误的@user.setter,直接在视图中使用模型实际的关联字段userkey:
- 修改Post模型:移除错误的
@user.setter,保留只读的user属性用于返回用户名
from django.db import models from accounts.models import CustomUser class Post(models.Model): # 外键关联 userkey = models.ForeignKey(CustomUser, on_delete=models.CASCADE) # 其他字段 title = models.CharField(max_length=100,blank=True) image= models.FileField(upload_to='files/', null=True, verbose_name="",blank=True) price = models.IntegerField(default=0,blank=True) description = models.TextField(blank=True) likes = models.IntegerField(default=0) tags = models.CharField(max_length=30,blank=True,default="tag1,tag2,...") date_modified = models.DateTimeField(auto_now=True,blank=True) created = models.DateTimeField(auto_now_add=True,blank=True) sold = models.BooleanField(default=False,blank=True) @property def user(self): return self.userkey.username @property def datejoined(self): return self.userkey.date_joined def __str__(self): return self.title
- 修改CreatePost视图:将
serializer.save(user=self.request.user)改为传入userkey
class CreatePost(generics.CreateAPIView): serializer_class = PostSerializer permission_classes = [permissions.IsAuthenticated] def perform_create(self,serializer): serializer.save(userkey = self.request.user)
方案二:正确实现@user.setter(保留user属性赋值)
如果你希望通过user属性来设置关联用户,需要正确实现setter方法,让它接收用户对象并赋值给userkey:
- 修改Post模型的setter:
from django.db import models from accounts.models import CustomUser class Post(models.Model): userkey = models.ForeignKey(CustomUser, on_delete=models.CASCADE) # 其他字段(同上) @property def user(self): return self.userkey.username @user.setter def user(self, user_obj): # 接收用户对象,赋值给userkey self.userkey = user_obj @property def datejoined(self): return self.userkey.date_joined def __str__(self): return self.title
- 视图代码保持不变:
class CreatePost(generics.CreateAPIView): serializer_class = PostSerializer permission_classes = [permissions.IsAuthenticated] def perform_create(self,serializer): serializer.save(user = self.request.user)
额外注意:序列化器配置
确保你的PostSerializer中,要么不包含user字段(因为它是模型的属性而非数据库字段),要么将其设置为只读字段:
from rest_framework import serializers from .models import Post class PostSerializer(serializers.ModelSerializer): user = serializers.ReadOnlyField() # 仅用于返回用户名,不接收输入 datejoined = serializers.ReadOnlyField() class Meta: model = Post fields = ['id', 'user', 'datejoined', 'title', 'image', 'price', 'description', 'likes', 'tags', 'date_modified', 'created', 'sold'] # 或者排除userkey,避免暴露给前端 # exclude = ['userkey']
内容的提问来源于stack exchange,提问作者tester0001
相关产品推荐
相关产品推荐

