Chcę serializować model, ale chcę dołączyć dodatkowe pole, które wymaga wykonywania niektórych wyszukiwań bazy danych w wystąpieniu modelu do serializacji:
class FooSerializer(serializers.ModelSerializer):
my_field = ... # result of some database queries on the input Foo object
class Meta:
model = Foo
fields = ('id', 'name', 'myfield')
Jaki jest właściwy sposób, aby to zrobić? Widzę, że można przekazać w dodatkowym „kontekście” do serializatora, czy poprawna odpowiedź jest przekazywana w dodatkowym polu w słowniku kontekstowym? Przy takim podejściu logika uzyskiwania pola, którego potrzebuję, nie byłaby niezależna od definicji serializatora, co jest idealne, ponieważ każda serializowana instancja będzie potrzebować my_field
. W innym miejscu dokumentacji serializatorów DRF jest napisane , że „dodatkowe pola mogą odpowiadać dowolnej właściwości lub wywoływać w modelu”. Czy mówię o dodatkowych polach? Czy powinienem zdefiniować funkcję w Foo
definicji modelu, która zwraca my_field
wartość, aw serializatorze podłączyć my_field do tego wywoływalnego? Jak to wygląda?
Z góry dziękuję, w razie potrzeby chętnie wyjaśnię pytanie.
field_name = serializers.SerializerMethodField()
idef get_field_name(self, obj):
foo
kiedy def a SerializerMethodField? kiedy używasz CreateAPIView, czy foo zostały zapisane, a następnie czy możesz użyć metody is_named_bar ()?Możesz zmienić metodę modelu na właściwość i używać jej w serializatorze za pomocą tego podejścia.
Edycja: Z ostatnimi wersjami frameworka REST (próbowałem 3.3.3), nie musisz zmieniać właściwości. Metoda modelu będzie działać dobrze.
źródło
variable = model_instance.my_field
daje taki sam wynik jakvariable = model_instance.my_field()
bez dekoratora. także: stackoverflow.com/a/6618176/2198571source='my_field'
nie jest już wymagane i zgłoś wyjątekW ostatniej wersji Django Rest Framework musisz stworzyć w swoim modelu metodę z nazwą pola, które chcesz dodać. Nie ma potrzeby
@property
isource='field'
zgłosi błąd.źródło
request
obiekt wewnątrz def foo (self), który mógłby modyfikować wartość foo? (przykład wyszukiwania na podstawie request.user)Moja odpowiedź na podobne pytanie ( tutaj ) może być przydatna.
Jeśli masz metodę modelu zdefiniowaną w następujący sposób:
Możesz dodać wynik wywołania tej metody do swojego serializatora w następujący sposób:
ps Ponieważ pole niestandardowe nie jest tak naprawdę polem w Twoim modelu, zazwyczaj chcesz ustawić je jako tylko do odczytu, na przykład:
źródło
jeśli chcesz czytać i pisać w swoim dodatkowym polu, możesz użyć nowego niestandardowego serializatora, który rozszerza serializatory.Serializer i używać go w ten sposób
używam tego w powiązanych polach zagnieżdżonych z pewną niestandardową logiką
źródło
W model.py
**
**
**
źródło
Jak powiedział w tym komentarzu programista chemiczny , w najnowszym DRF można to zrobić w następujący sposób:
Źródło dokumentacji DRF
źródło