/ / django rest framework: предварително извличане на начални данни в сериализатор - python, django, django-rest-framework, serializer

django rest framework: Предварително извличане на първоначални данни в serializer - python, django, django-rest-framework, serializer

Знам, че django има select_related иprefetch_related, който може да се използва при запитване на елементи от база данни за увеличаване на неговата производителност, и може да се използва в двойка с вложените сериализатори на django rest framework.

Въпреки това, проблемът идва, когато искам да използвам сериализатора, за да създам моя модел например:

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

Например искам да създам компания с множество служители, като:

request.POST:

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

тогава мога да използвам CompanySerializer (request.POST), нали?

Въпреки това, когато спасявам този сериализатор,EmployeeSerializer ще претърси всеки служител и запитване на staff.card_set, което води до много SQL заявки. Има ли някакъв начин да го направим подобно на prefetch_related?

Благодаря

Отговори:

0 за отговор № 1

Тъй като въпросът е твърде отворен, аз ще дам указанията.

Django ORM ви позволява да създадете няколко копия едновременно, като използвате bulk_create.

Също така имайте предвид, че не трябва да се обаждате на друг сериализатор от сериализаторската програма за създаване / обновяване, както е показано в документацията


0 за отговор № 2

Можете да изпращате допълнителна информация във вашия сериализатор чрез 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)}
)
...

След това го използвайте при проверката:

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