【发布时间】:2018-07-09 14:26:00
【问题描述】:
我的问题与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)
此代码的行为与我想要的一样,但会强制信息冗余并且不利用底层关系数据库。我尝试使用链接问题中的信息在平面 json 中实现“在数据库上写入用户 id,但在“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 错误。
问题:如何将用户 ID 从 request.user 信息写入数据库对象以引用实际用户 ID,但在 projectsView 端点上的 GET 请求中返回简单用户名,而不在模型中显式存储用户名?或者更一般地说,如何使用默认的序列化 DRF 功能和默认的 DRF 视图 mixins 将数据库对象(Django 模型)序列化为客户 json 响应?
问题的另一种表述:如何在我的模型中存储对另一个 DB 记录的 ID 引用(可以在没有有效负载提供的情况下访问它)但在序列化程序级别反序列化来自该对象引用的派生信息,例如作为被引用对象的一个特定字段?
【问题讨论】:
-
如果您想存储当前用户,请将其从序列化程序中删除,然后从视图中填充您的模型。如果这是你的答案,请告诉我完成它
-
看我贴的sn-p视图。听起来你根本没有回答这个问题。
-
我的意思是为什么你对 post 和 get 使用相同的序列化程序,你可以为 get 编写另一个序列化程序,其中一个为用户带来所有细节,对于 post 你也可以删除 user_id然后用另一种方法存储在数据库中
-
我对 DRF 序列化程序的理解是,有一种方法可以从中定义序列化和反序列化,并从视图中抽象出模型,这与您的建议完全相反。但我可能误解了一些东西......
标签: django serialization django-models django-rest-framework