【问题标题】:what is the control flow of django rest frameworkdjango rest框架的控制流程是什么
【发布时间】:2015-08-06 23:32:28
【问题描述】:

我正在为 webapp 开发一个 api。我最初使用的是 sweetpie 并切换到django-rest-framework (drf)。 Drf 对我来说似乎很容易。我打算做的是创建嵌套的用户配置文件对象。我的模型如下

from django.db import models
from django.contrib.auth.models import User

class nestedmodel(models.Model):
    info = models.CharField(null=True, blank=True, max_length=100)


class UserProfile(models.Model):
    add_info = models.CharField(null=True, blank=True, max_length=100)
    user = models.OneToOneField(User)
    nst = models.ForeignKey(nestedmodel)

我有其他具有外键关系的模型。我的序列化器如下

from django.contrib.auth.models import User, Group
from rest_framework import serializers
from quickstart.models import UserProfile, nestedmodel


class NestedSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = nestedmodel
        fields = ('info', )

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')

class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    nst = NestedSerializer()
    class Meta:
        model = UserProfile
        user = UserSerializer(many=True)
        nested = NestedSerializer(many=True)
        fields = ('nst', 'user')

我可以覆盖create(self, validated_data): 之类的方法而不会出现任何问题。但我想知道的是to which method should the response returned by create() goes,或者换句话说Which method calls create()。在 sweetpie Resources.py 中是要覆盖以实现自定义方法的文件。 Resources.py 包含调用方法的顺序。 drf 中的哪个文件具有相同的目的,并说明了像 Tastepie 中的 Resources.py 这样的控制流?

【问题讨论】:

  • 不确定我是否理解您的问题,但create 的结果不是Response 包含新创建的对象并且通常返回给查看器的对象吗?
  • 哦..是的。我将编辑问题。

标签: django django-rest-framework tastypie control-flow


【解决方案1】:

所以流程是这样的:

  1. Viewset 的create() 方法在CreateModelMixin 中实现
  2. 这会创建序列化程序并对其进行验证。一旦有效,它将使用视图集的perform_create()
  3. 调用序列化程序的save()方法
  4. 然后依次调用序列化程序 create()update(),具体取决于实例是否已传递给序列化程序(它不在步骤 1 中)
  5. create()update() 然后创建/更新实例,然后将其保存在 serializer.instance
  6. Viewset 然后返回来自serializer.data 的数据的响应
  7. serializer.data 实际上是序列化器上的一个属性,负责将实例序列化为字典
  8. 为了序列化数据,使用to_representation()
  9. 然后响应数据(Python dict)通过renderers 呈现为输出格式,可以是 json、xml 等

Resources.py 包含调用方法的顺序。 drf 中的哪个文件具有相同的目的,并说明了像 Tastepie 中的 Resources.py 一样的控制流程?

猜猜这将是文件的组合。考虑到您所接触的类/概念可能会更好,因为在 DRF 中,您可以从多个事物中继承来创建您的类。所以将所有东西粘合在一起的东西是viewsets。然后是各种视图集混合,它们实际上将视图集粘合到序列化器和不同的 CRUD 操作。

【讨论】:

  • 感谢您的回复。 save()之后,调用什么方法返回json响应?还是用 save() 本身写的?
  • 抱歉耽搁了。控制流很大程度上取决于被继承的类。无论如何,如果对象存在,我找不到获取对象的方法,否则创建一个新对象。我尝试覆盖HyperLinkedModelSerializerModelserializersave()create() 方法。无论如何,控制都不会传递给这两种方法。我认为this field must be unique 如果存在对象并且该对象用作不可为空的字段,则会在验证阶段生成。但它仍然不清楚它是如何在验证时产生的,因为 django 在创建对象时会生成该错误。
  • update_or_create 并不真正适用于 RESTful API。用户要么通过POST*-list URL 上创建对象(例如/api/resource/),要么使用PUT 更新*-detail URL 上的对象(例如/api/resource/<pk>/)。将两者结合起来并不是一个好主意。如果您绝对需要,那么您应该为此创建一个自定义路由...
  • 我发现Classy DRF 是理解这些生命周期问题的宝贵资源
  • 不敢相信这不包括在 DRF 文档网站中,这条信息是如此重要和基础。当我想开始更改某些内容时非常困惑,但最终在没有线索的情况下在视图集和序列化程序之间弹跳。这个答案帮助了很多!
【解决方案2】:

我自己想出了问题的第二部分。获取/创建对象可以通过在views.py 中覆盖def create(self, request, *args, **kwargs): 中使用自定义代码来完成。代码如下粘贴。再一次,为了清楚起见,这是views.py 而不是serializers.py。也可以从 request.DATA 访问带有发布值的 json

class NestedViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows Nested objects to be viewed or edited.
    """
    queryset = nestedmodel.objects.all()
    serializer_class = NestedSerializer
    def create(self, request, *args, **kwargs):
        info = request.DATA['info']
        user = User.objects.get(username=request.DATA['user']['username'])
        profile = UserProfile.objects.get(user=user)
        nst = nestedmodel.objects.create(info=info, user=user, profile=profile)
        serialized_obj = serializers.serialize('json', [ nst, ])
        json_serialized = json.loads(serialized_obj)
        data = json.dumps(json_serialized[0])
        return Response(data)

感谢@miki275 的帮助 :)

【讨论】:

  • 仅供参考。您的解决方案并没有真正使用任何 DRF 工具,例如序列化程序
猜你喜欢
  • 2020-11-06
  • 2021-08-07
  • 2014-06-23
  • 2019-08-02
  • 1970-01-01
  • 2020-01-01
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
相关资源
最近更新 更多