Próbuję zaimplementować zagnieżdżony zasób, w którym jedno z jego pól zależy od wartości z jego zasobu nadrzędnego.Django REST framework: czy zagnieżdżony obiekt może uzyskać dostęp do szczegółów obiektu nadrzędnego w widoku listy?
Załóżmy, że budujemy system dla firmy, która dostarcza informacji o swoich klientach oraz danych o sprzedaży dla sprzedawców firmy. Mamy więc dwa modele: Klient i Rep. Rep może sprzedać więcej niż jednego klienta.
URL, które zwraca wszystkich klientów: /api/1.0/customers/
URL dla konkretnego klienta: /api/1.0/customers/123/
URL informacji o klientach specyficzne dla konkretnego przedstawiciela handlowego: /api/1.0/customers/123/rep/9/
Uwaga URL rep zawiera klienta ID, a także identyfikator rep.
Chcę, aby adres URL klienta zwrócił zagnieżdżony zasób zawierający informacje podsumowujące o przedstawicielu oraz hiperłącze do pełnych informacji specyficznych dla klienta dla tego przedstawiciela. Jest to wyjście z adresu URL dla wszystkich klientów:
[
{
"id": 100,
"customer_name": "DolManSaxLil",
"rep": {
"id": 4,
"annual_sales": 1500.01,
"name": "Fred",
"url": "http://localhost:8000/api/1.0/customer/100/rep/4/"
}
},
{
"id": 200,
"customer_name": "Hotblack",
"rep": {
"id": 4,
"annual_sales": 10500.42,
"name": "Fred",
"url": "http://localhost:8000/api/1.0/customer/200/rep/4/"
}
}
]
Aby to realizować możemy zdefiniować dwa serializers:
class CustomerSummarySerializer(serializers.HyperlinkedModelSerializer):
id = ...
name = ...
rep = RepSummarySerializer(read_only=True)
class RepSummarySerializer(serializers.HyperlinkedModelSerializer):
id = ...
annual_sales = ...
name = ....
url = serializers.SerializerMethodField('get_rep_url')
Problem jestem stoi to, że nie może pracować się, jak uzyskać dostęp do aktualnego klienta .id z funkcji RepSummarySerializer.get_rep_url
. Jest to możliwe w widoku szczegółów, jak klient jest utrzymywany w self.parent.obj
:
def get_rep_url(self, obj):
customer_id = self.parent.obj.id
url = reverse('api_customer_rep',
kwargs={'customer_id': customer_id,
'rep_id': obj.id},
request=serializer.context.get('request'))
return url
Jednak w widoku listy, self.parent.obj
jest QuerySet obiektów klienta i nie widzę żadnego sposobu identyfikacji bieżącego klienta. Czy jest jakiś sposób na zrobienie tego? Czy przegapiłem coś oczywistego?
Całkiem eleganckie rozwiązanie.Działa bez zarzutu! Wielkie dzięki! – gregoltsov
Świetne rozwiązanie, ale musiałem zmienić rep = obj.rep na rep = obj.rep.get() –