您的位置:首页 > 文旅 > 美景 > 重庆建设工程信息网30系统_免费建工作室网站_seo排名优化app_网络营销成功的案例分析

重庆建设工程信息网30系统_免费建工作室网站_seo排名优化app_网络营销成功的案例分析

2024/10/6 10:39:10 来源:https://blog.csdn.net/2201_75632987/article/details/142662704  浏览:    关键词:重庆建设工程信息网30系统_免费建工作室网站_seo排名优化app_网络营销成功的案例分析
重庆建设工程信息网30系统_免费建工作室网站_seo排名优化app_网络营销成功的案例分析

DRF的ModelSerializer序列化器与Django的Model模型紧密映射,本文将通过简单的示例介绍几种处理关联关系的方法。

1. 创建模型和初始数据

创建模型

from django.db import modelsclass Product(models.Model):product_name = models.CharField(max_length=255)quantity = models.IntegerField()class Component(models.Model):product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='components')component_name = models.CharField(max_length=255)code = models.CharField(max_length=255)quantity = models.IntegerField()class Meta:ordering = ['product']def __str__(self):return f'{self.code}-{self.component_name}'

创建数据

>>> from api.models import Product, Component
>>> p1 = Product.objects.create(product_name="盖子", quantity=30)
>>> Component.objects.create(product=p1, component_name='纤维板', code='XYB', quantity=5)
>>> Component.objects.create(product=p1, component_name='螺丝', code='LS', quantity=10)
>>> Component.objects.create(product=p1, component_name='密封条', code='MFT', quantity=20)

2. 字符串关系字段

使用StringRelatedField

from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components = serializers.StringRelatedField(many=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']

执行查询和序列化

>>> from api.models import Product
>>> p1 = Product.objects.prefetch_related('components').get(pk=1)
>>> from api.serializers import ProductSerializer
>>> ps = ProductSerializer(p1)
>>> ps.data
# {'product_name': '盖子', 'quantity': 30, 'components': ['XYB-纤维板', 'LS-螺丝', 'MFT-密封条']}

效果如下:

{'product_name': '盖子', 'quantity': 30, 'components': ['XYB-纤维板', 'LS-螺丝', 'MFT-密封条']
}

注意观察获取查询集的代码:Product.objects.prefetch_related('components').get(pk=1)不难发现我们使用了prefetch_related来获取查询集,如果一次查询大量的Product,不使用prefetch_related将会导致严重的性能问题(N+1问题)。DRF的序列化器不会为你自动优化。当然我们的示例中影响不大,因为只获取了一个查询集。

3. 主键关系字段

使用PrimaryKeyRelatedField

from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components =  serializers.PrimaryKeyRelatedField(many=True, read_only=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']

效果如下:

{'product_name': '盖子', 'quantity': 30, 'components': [1, 2, 3]
}

4. 指定关系字段

使用SlugRelatedField可以指定字段来表示关联关系:

from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components =  serializers.SlugRelatedField(many=True,read_only=True,slug_field='code')class Meta:model = Productfields = ['product_name', 'quantity', 'components']

效果如下:

{'product_name': '盖子', 'quantity': 30, 'components': ['XYB', 'LS', 'MFT']
}

5. 嵌套序列化器

from rest_framework import serializers
from .models import Product, Componentclass ComponentSerializer(serializers.ModelSerializer):class Meta:model = Componentfields = ['component_name', 'code', 'quantity']class ProductSerializer(serializers.ModelSerializer):components =  ComponentSerializer(many=True, read_only=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']

效果如下:

{"product_name": "盖子","quantity": 30,"components": [{"component_name": "纤维板","code": "XYB","quantity": 5},{"component_name": "螺丝","code": "LS","quantity": 10},{"component_name": "密封条","code": "MFT","quantity": 20}]
}

6. 可写嵌套

默认上面创建的嵌套序列化器是只读的,可写嵌套需要实现updatecreate两者或其一:

from rest_framework import serializers
from .models import Product, Componentclass ComponentSerializer(serializers.ModelSerializer):class Meta:model = Componentfields = ['component_name', 'code', 'quantity']class ProductSerializer(serializers.ModelSerializer):components =  ComponentSerializer(many=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']def create(self, validated_data):components_data = validated_data.pop('components')product = Product.objects.create(**validated_data)for component_data in components_data:Component.objects.create(product=product, **component_data)return product

可以使用此序列化器创建实例:

>>> data = {"product_name": "电机","quantity": 1,"components": [{"component_name": "铝型材","code": "LXC","quantity": 5},{"component_name": "螺栓","code": "LSHUN","quantity": 10},]
}
>>> from api.serializers import ProductSerializer
>>> s = ProductSerializer(data=data)
>>> s.is_valid()
# True
>>> s.save()
# <Product: Product object (2)>

7. 总结注意事项

  1. 关联关系注意使用prefetch_related获取查询集。
  2. 可写嵌套序列化器必须自己实现create方法update方法两者或其一。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com