Utilizzo Django 1.6 (molto presto l'aggiornamento a 1.8), Python 2.7 e DRF 3.2.5 (molto presto l'aggiornamento all'ultima versione).Estendere il framework del resto django per consentire l'ereditarietà del contesto nei serializzatori nidificati
Ho una serie di serializzatori profondamente annidati (~ 10 livelli di profondità, con un totale di 20-30 modelli serializzati). Sto tentando di aggiungere un flag booleano al contesto, che determinerà se la gerarchia dell'output serializzato sarà dettagliata (include tutti i campi dei modelli) o di base (solo parte dei campi).
ho scritto il seguente codice (frammento di parziale):
from rest_framework import serializers
from app.models import Institute, Department, Member
class MemberSerializer(serializers.ModelSerializer):
def get_fields(self):
fields = super(MemberSerializer, self).get_fields()
if self.context['basic_view']:
for field in ['height', 'weight']:
del fields[field]
return fields
class Meta:
model = Member
fields = ('id', 'birth_date', 'height', 'weight')
class DepartmentSerializer(serializers.ModelSerializer):
members = MemberSerializer(many=True, read_only=True)
def get_fields(self):
fields = super(DepartmentSerializer, self).get_fields()
if self.context['basic_view']:
for field in ['type', 'manager']:
del fields[field]
return fields
class Meta:
model = Department
fields = ('id', 'name', 'type', 'manager', 'members')
class InstituteSerializer(serializers.ModelSerializer):
departments = DepartmentSerializer(many=True, read_only=True)
def get_fields(self):
fields = super(InstituteSerializer, self).get_fields()
if self.context['basic_view']:
for field in ['name', 'type']:
del fields[field]
return fields
class Meta:
model = Institute
fields = ('id', 'name', 'type', 'departments')
def get_entities(is_basic_view):
institutes_list = Institute.objects.all()
serializer = InstituteSerializer(institutes_list, many=True, read_only=True, context={'basic_view': is_basic_view})
return serializer.data
Ma poi scoperto che il 'contesto' che viene passato da 'get_entities' a 'InstituteSerializer' non viene passato-on per i serializzatori nidificati . Significa che nell'esempio sopra - InstituteSerializer ha 'basic_view' nel 'contesto', ma MemberSerializer & DepartmentSerializer no.
Ho trovato una soluzione di lavoro in context in nested serializers django rest framework: per utilizzare SerializerMethodField per campo nidificato (ad esempio "reparti") e nel metodo 'get_' per passare manualmente il contesto. Il mio problema con questa soluzione è che è necessario incorporare questo codice 20-30 volte nel mio codice, eventualmente raddoppiando il numero di linee di origine.
La mia richiesta - se qualcuno ha (o può aiutare a implementare) un'estensione per serializers.ModelSerializer, che otterrà un parametro aggiuntivo al momento della costruzione, ad es. 'Inherit_context'. Quindi l'unica cosa che ho bisogno di cambiare nelle mie classi, per esempio in 'InstituteSerializer', è l'aggiunta di quel parametro:
class InstituteSerializer(serializers.ModelSerializer):
departments = DepartmentSerializer(many=True, read_only=True, inherit_context=True)
def get_fields(self):
fields = super(InstituteSerializer, self).get_fields()
if self.context['basic_view']:
for field in ['name', 'type']:
del fields[field]
return fields
class Meta:
model = Institute
fields = ('id', 'name', 'type', 'departments')
Forse non capisco bene, ma perché non si passa semplicemente a quel contesto? Per esempio. chiamando 'dipartimenti = DepartmentSerializer (many = True, read_only = True, context = self.context)' da 'InstituteSerializer' con il contesto che ha ricevuto in precedenza? – C14L
@ C14L non è possibile poiché 'self' è un riferimento non risolto a questo punto –