栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Django REST Framework POST嵌套对象

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django REST Framework POST嵌套对象

你的问题涉及DRF中的复杂问题,因此需要进行一些解释和讨论,以了解序列化程序和视图集的工作方式。

我将讨论代表你的问题

Subject
,并
Class
通过使用不同的HTTP方法数据的不同表示通过相同的端点数据,因为这通常是当人们希望代表自己的嵌套格式的数据的问题; 他们希望为用户界面提供足够的信息以供清洁使用,例如通过下拉选择器。

默认情况下,Django和Django REST framework(DRF )通过其主键引用相关对象(your Subject和

Class
)。默认情况下,这些是使用Django自动递增的整数键。如果要通过其他方式引用它们,则必须为此编写重写。有几种不同的选择。

  1. 第一种选择是专门化你的创建和更新逻辑:通过其他一些属性来引用你的类,并手动编写用于自己创建的查找,或者将要引用的键设置为类的主键。你可以将类的名称,UUID或任何其他属性设置为主数据库键,只要它是唯一的单个字段即可(我之所以提及此原因是因为你目前正在
    Class
    用由复合(数字,字母)搜索词组成的复合搜索。例如,你可以在
    create
    视图方法中覆盖相关的对象查找(对于POST),但是随后你也必须在
    update
    视图方法中处理类似的查找(对于PUT和PATCH)。
  2. 其次,我认为最好的选择是专门化对象的表示形式:通常通过主键引用你的类,并创建一个用于读取对象的序列化程序,以及一个用于创建和更新对象的序列化程序。这可以通过序列化器类的继承和覆盖你的表示来轻松实现。在POST,PUT,PATCH等请求中使用主键来更新你的类引用和外键。
    选项1:在创建和更新中使用任意属性查找类和主题:

将嵌套的类序列化器设置为只读:

class ExamSerializer(serializers.ModelSerializer):    subject = SubjectSerializer(read_only=True)    clazz = ClassSerializer(read_only=True)

覆盖视图的创建,以在自由格式属性上查找相关类。此外,请检查DRF如何通过mixins实现此功能。你还必须重写update方法以正确处理这些问题,并且如果采取以下方法PATCH,除了PUT(更新)之外,还应考虑(部分更新)支持:

def create(self, request):    # Look up objects by arbitrary attributes.    # You can check here if your students are participating    # the classes and have taken the subjects they sign up for.    subject = get_object_or_404(Subject, title=request.data.get('subject'))    clazz = get_object_or_404(        Class,         number=request.data.get('clazz_number')        letter=request.data.get('clazz_letter')    )    serializer = self.get_serializer(data=request.data)    serializer.is_valid(raise_exception=True)    serializer.save(clazz=clazz, subject=subject)    headers = self.get_success_headers(serializer.data)    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

选项2:专用于序列化器进行读写和使用主键;这是惯用的方法:

首先定义一个你希望用于常规操作(POST,PUT,PATCH)的默认ModelSerializer:

class ExamSerializer(serializers.ModelSerializer)    class meta:        model = Exam        fields = ('id', 'subject', 'clazz', 'topic', 'date', 'details')

然后,使用你要提供给它们的表示形式来覆盖必填字段,以读取数据(GET):

class ExamReadSerializer(ExamSerializer):     subject = SubjectSerializer(read_only=True)     clazz = ClassSerializer(read_only=True)

然后为ViewSet 指定要用于不同操作的序列化器。在这里,我们返回嵌套的Subject和Class数据以进行读取操作,但仅将其主键用于更新操作(更为简单):

class ExamViewSet(viewsets.ModelViewSet):     queryset = Exam.objects.all()     def get_serializer_class(self):         # Define your HTTP method-to-serializer mapping freely.         # This also works with CoreAPI and Swagger documentation,         # which produces clean and readable API documentation,         # so I have chosen to believe this is the way the         # Django REST framework author intended things to work:         if self.request.method in ['GET']:  # Since the ReadSerializer does nested lookups  # in multiple tables, only use it when necessary  return ExamReadSerializer         return ExamSerializer

如你所见,选项2似乎不太复杂且不易出错,在DRF(get_serializer_class实现)之上仅包含3行手写代码。只需让框架的逻辑为你找出对象的表示形式以及对象的创建和更新。

我看到了许多其他方法,但是到目前为止,这些方法为我提供了最少的代码来维护,并以干净的方式利用DRF的设计。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/407788.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号