简体   繁体   English

Django Rest框架:在序列化程序中预取初始数据

[英]django rest framework: prefetch an initial data in serializer

I know that django has select_related and prefetch_related that can be used when querying items from database to increase its performance, and it can be used in pair with django rest framework's nested serializer. 我知道django具有select_related和prefetch_related,可以在从数据库查询项目以提高其性能时使用,并且可以与django rest框架的嵌套序列化程序一起使用。

However, the problem come when I want to use the serializer to create my model for example: 但是,当我想使用序列化程序来创建模型时,问题就来了:

class CompanySerializer(serializer.serializers):
    employee_set = serializers.JSONField()
    class Meta:
        model = Company
        fields = ('id', 'employee_set')
    def create(self, validated_data):
        employee_set = validated_data.pop('employee_set')
        for employee in employee_set:
            serializer = EmployeeSerializer(data=employee)
            serializer.is_valid(raise_exception=True)
            serializer.save()

class EmployeeSerializer(serializer.serializers):
    card = serializers.PrimaryKeyRelatedField(queryset=Card.objects.all())
    class Meta:
        model = Employee
        fields = ('id', 'name', 'card')
    def validate(self, obj):
        if card.employee_set.all().count() > 3:
            raise serializers.ValidationError({'_error': 'invalid})
        return data

For example, I want to create a company with multiple employee like: 例如,我想创建一个拥有多个员工的公司,例如:

request.POST: request.POST:

{
    employee_set: [
        { name: 'tim', card: 1 },
        { name: 'bob', card: 1 },
        { name: 'jimmy', card: 2},
    ]
}

then I can use CompanySerializer(request.POST), right? 然后我可以使用CompanySerializer(request.POST),对吗?

However, when I am saving this serializer, the EmployeeSerializer will iterate over each employee and query employee.card_set, which result in a lot of sql queries. 但是,当我保存此序列化程序时,EmployeeSerializer将遍历每个员工并查询employee.card_set,这将导致大量的SQL查询。 Is there any way to do it similar like prefetch_related? 有没有办法像prefetch_related这样呢?

thanks 谢谢

As the question is too open, I'll give the directions. 由于问题太开放,我将给出指示。

Django ORM allows you to create several instances at once using bulk_create . Django ORM允许您使用bulk_create一次创建多个实例。

Also note that you should not call another serializer from a serializer's create/update, as shown in the documentation 还要注意,您不应从序列化程序的创建/更新中调用另一个序列化程序,如文档所示

You can send extra information into your serializer, via context 您可以通过context将其他信息发送到序列化器context

# use select_related or prefetech_related to get this value
card_counters = {'card_id1': 1, 'card_id2': 3, ...}

for employee in employee_set:
    serializer = EmployeeSerializer(
        data=employee, 
        context={'card_counter': card_counters.get(employee['card_id'], 0)}
    )
    ...

And then use it when doing the validation: 然后在进行验证时使用它:

def validate(self, obj):
    if self.context['card_counter'] > 3:
        raise serializers.ValidationError({'_error': 'invalid})
    return data

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM