ProblemDjango REST Framework i stosunki generyczne
Mam model z następujących standardowych pól rodzajowe klucza obcego:
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
event_object = generic.GenericForeignKey('content_type', 'object_id')
Według docs reszta ramowego, mogę wykonać następujące czynności, aby serialise to poprawnie:
class WhateverSerializer(serializers.ModelSerializer):
event_object = serializers.RelatedField(source='event_object')
działa to dobrze, jednak w dwóch innych związanych z sytuacjami, nie mogę dostać rzeczy robocze:
- Chciałbym użyć
HyperlinkedRelatedField
. To pole wymaga argumentu nazwa_widoku, coś, czego nie mogę zadeklarować, ponieważ nazwa widoku zmienia się w powiązanym modelu. Rozwiązałem to, używającSerializerMethodField
, tworząc instancjęHyperlinkedIdentityField
w czasie wykonywania i zwracając jej metodęfield_to_native
(patrz fragment poniżej). To nie jest bardzo eleganckie. - Chciałbym zagnieździć obiekt powiązany bezpośrednio w serializacji, mówiąc:
event_object = SoAndSoSerializer(source='event_object')
. Jedyne rozwiązanie, jakie widzę, to chodzić po każdym zdefiniowanym i sprawdzonym, który ma prawidłowy model, a następnie użyć tego. Ponownie, nie jest to bardzo eleganckie.
Pytania
jest HyperlinkRelatedField przeznaczona do pracy w całej relacji rodzajowe? Czy ja tylko popełniłem błąd? Czy istnieje oczywiste rozwiązanie polegające na tym, że brakuje mi właściwej odpowiedzi?
Code Snippet
nieeleganckie rozwiązanie o którym mowa w podpunkcie 1 powyżej:
class WhateverSerializer(DefaultSerializer):
event_object_url = serializers.SerializerMethodField('get_related_object_url')
# ...
def get_related_object_url(self, obj):
obj = obj.event_object
default_view_name = '%(model_name)s-detail'
format_kwargs = {
'app_label': obj._meta.app_label,
'model_name': obj._meta.object_name.lower()
}
view_name = default_view_name % format_kwargs
s = serializers.HyperlinkedIdentityField(source=obj, view_name=view_name)
s.initialize(self, None)
return s.field_to_native(obj, None)
Należy pamiętać, że do pola należy użyć tylko argumentu "source", jeśli źródło różni się od nazwy pola. Możesz go upuścić w przypadku "event_object". –