Знам, че 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