Django размещение логики в представлении vs сериализатор vs модель лучший подход
Каков наилучший подход к размещению логики и что лучше в моем текущем сценарии, где у меня есть представление, которое использует запрос + подзапрос для получения и возврата данных.
@action(detail=False, methods=["get"], url_name="inventory")
def inventory(
self, request: Request, *args: None, **kwargs: None
) -> Response:
required = (
ProductionJob.objects.filter(item=OuterRef("pk"))
.order_by()
.filter(status="Pending")
.values("item")
.annotate(
amount_sum=Sum(
"required_item", output_field=FloatField()
)
)
.values("amount_sum")
)
data = (
Item.objects.select_related("supplier")
.prefetch_related("item_jobs")
.annotate(
item_required=Coalesce(
Subquery(required),
0,
output_field=FloatField(),
)
)
.values(
"id",
"article_id",
"composition",
"width_meter",
required_for_jobs=Sum("item_required"),
supplier_name=F("supplier__name"),
)
)
return Response(data=data, status=HTTP_200_OK)
Вопрос в том, в каком месте лучше всего хранить этот код. Его можно поместить в QuerySet модели или если его нужно переместить в сериализатор, то как?
Спасибо.
Я перенес код в сериализатор таким образом. Вот представление:
@action(detail=False, methods=["get"], url_name="inventory")
def inventory(self, request: Request, *args: None, **kwargs: None) -> Response:
queryset = Item.objects.select_related("supplier").prefetch_related(
"item_jobs"
)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, status=HTTP_200_OK)
И сериализатор:
class ItemInventorySerializer(ModelSerializer[Item]):
supplier_name = SerializerMethodField(required=False)
required_for_jobs = SerializerMethodField(required=False)
class Meta:
model = Item
fields = [
"id",
"article_id",
"composition",
"width_meter",
"required_for_jobs",
"supplier_name",
]
def get_supplier_name(self, obj: Item) -> str:
return obj.supplier.name
def get_required_for_jobs(self, obj: Item) -> Optional[float]:
return obj.item_jobs.aggregate(
required_for_jobs=Coalesce(
Sum("required_item_meters"), 0, output_field=FloatField()
)
).get("required_for_jobs")
Остается вопрос, что лучше. Хранить это в представлении или в сериализаторе. Спасибо.