DRF序列化器-可写嵌套(项目不使用数据库关联关系)

注: 若使用数据局关联关系,请参考这里

models.py

class DeviceInfo(BaseModel):
    name = models.CharField(max_length=128, blank=True, null=True, help_text='名称')
    ip = models.CharField(max_length=32, blank=True, null=True, help_text='IP地址')
    ....
    class Meta:
        # 排序,倒序用'-'
        # ordering = ['order_date']
        verbose_name_plural = "设备信息"

    def get_ability(self):
        return DeviceAbility.objects.get(host_id=self.id)


class DeviceAbility(models.Model):
    host_id = models.IntegerField(blank=True, null=True, help_text='设备ID')
    host_ip = models.CharField(max_length=32, blank=True, null=True, help_text='设备IP')

serializers.py

from django.db import transaction
class TestSerializer(DynamicFieldsModelSerializer):
    # one-to-many demo
    # source的方法对应的是DeviceInfo的get_ability方法
    ability = DeviceAbilitySerializer(source='get_ability', fields=('host_id', 'host_ip'))
    # ability = DeviceAbilitySerializer(source='get_ability', fields=('host_id', 'host_ip'), many=True)

    class Meta:
        model = DeviceInfo
        fields = '__all__'

    def update(self, instance, validated_data):
        super().update(instance, validated_data)

    @transaction.atomic  #事务,执行完再提交
    def create(self, validated_data):
        ability_data = validated_data.pop('get_ability')
        instance = DeviceInfo.objects.create(**validated_data)
        ability_data['host_id'] = instance.id
        ability_data['host_ip'] = instance.ip
        DeviceAbility.objects.create(**ability_data)
        # for data in ability_data:
        #     DeviceAbility.objects.create(data)
        return instance

view.py

class TestsView(generics.ListCreateAPIView):
    queryset = DeviceInfo.objects.all()
    serializer_class = TestSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # self.perform_create(serializer)
        serializer.save()  # save会调用TestSerializer的create方法

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

url.py

urlpatterns = [
    path('tests/', views.TestsView.as_view()),
]

参考地址:
https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers
https://zhuanlan.zhihu.com/p/274507545 [source的用法]

posted @ 2022-01-06 19:08  TasteL  阅读(378)  评论(0编辑  收藏  举报