我的问题与this one有些相关,但存在一些差异 . 我有一个类似于这个的模型:
class Project(models.Model):
project_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
created_by_id = models.ForeignKey('auth.User', related_name='project', on_delete=models.SET_NULL, blank=True, null=True)
created_by = models.CharField(max_length=255, default="unknown")
created = models.DateTimeField(auto_now_add=True)
使用以下序列化程序:
class ProjectSerializer(serializers.ModelSerializer):
created_by = serializers.ReadOnlyField(source='created_by_id.username')
class Meta:
model = Project
fields = ('project_id', 'created_by', 'created')
和相应的观点:
class projectsView(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def perform_create(self, serializer):
serializer.save(created_by_id=self.request.user)
此代码的行为与我想要的一样,但强制信息冗余,并且不利用底层关系数据库 . 我试图使用链接问题中的信息来实现“在数据库上写入用户ID,但在平面json中返回用户名”get“”但没有成功:
删除模型中的“created_by”字段 . 用以下代替序列化器:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
class ProjectSerializer(serializers.ModelSerializer):
created_by = UserSerializer(read_only=True)
created_by_id = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), source='created_by', write_only=True)
class Meta:
model = Project
fields = ('project_id', 'created_by', 'created_by_id', 'created')
哪个不会100%给我我想要的东西,即用平面json中的用户名替换用户ID但返回类似的内容: {'project_id': <uuid>, 'created_by': <user json object>, 'created': <data>}
. 但我仍然得到一个 {'created_by_id': ['This field is required.']}
400错误 .
问题:如何从request.user信息向数据库对象写入用户id以引用实际用户ID,但在projectsView endpoints 上的GET请求中返回一个简单的用户名,而不在模型中明确存储用户名?或者更一般地说,如何使用默认的序列化DRF功能和默认的DRF视图mixins将数据库对象(Django模型)序列化为客户json响应?
问题的替代公式:如何将ID引用存储到我的模型中的另一个DB记录(可以在没有由有效负载提供的情况下访问),但是在序列化程序级别从该对象引用反序列化派生信息,例如一个特定的引用对象的字段?
2 回答
我建议你使用 Two different serializers 进行
Get
和POST
操作 . 将你的_1547422改为另外,如果您正在寻找CRUD operations,我会推荐API类的ModelViewSet . 因此,视图将是这样的,
那么,创建
Project
的有效负载是,您应该记住的一件事,当您尝试创建
Project
用户时必须登录UPDATE - 1
serializer.py
views.py
该错误位于write_only字段选项中 .
required
参数默认值设置为True
,而目的是在我们查看模型时不要求它 . 在视图中,我使用perform_create作为后处理来保存Model DB表示 . 由于required
默认值在创建级别为True
,因此数据库的第一个.save()
失败 . 由于这纯粹是内部逻辑,因此不需要 . 所以只需在PrimaryKeyRelatedField
上添加required=False
选项即可完成工作:如果我坚持纯粹在串行器级别使用逻辑进行反序列化,那么在模型级强制执行required = True也需要覆盖串行器的.save函数 . 可能有一种方法可以在序列化程序中获取用户参考,以使视图实现更加'default' ...这可以通过使用Jerin中的默认值来完成:
现在只使用用户名来展开json,你需要使用一个slug字段而不是UserSerializer:
然后,只有用户模型的用户名字段值将显示在get有效内容的create_by json标记上 .
UPDATE - 1
经过一些更多调整后,我提出了最终版本: