Cómo publicar en una API del marco REST de Django con modelos relacionados

Tengo dos modelos relacionados (Eventos + Ubicaciones) con un serialzer que se muestra a continuación:

class Locations title = models.CharField(max_length=250) address = model.CharField(max_length=250) class Events title = models.CharField(max_length=250) locations = models.ForeignKey(Locations, related_name='events' class EventsSerializer(serializers.ModelSerializer): class Meta: model = Events depth = 1 

Establecí la profundidad a 1 en el serializador para poder obtener la información del modelo de Locations lugar de una única id . Al hacer esto, sin embargo, no puedo publicar en eventos con la información de ubicación. Solo puedo realizar una publicación con el atributo de título. Si elimino la opción de profundidad en el serializador, puedo realizar la publicación con el título y la identificación de ubicación.

Intenté crear un segundo serializador (EventsSerialzerB) sin el campo de profundidad con la intención de usar el primero como una respuesta de solo lectura. Sin embargo, cuando creé un segundo serializador, un conjunto de vistas y lo añadí al enrutador, se anularía automáticamente. El conjunto de vistas original.

¿Puedo crear un serializador que genere los campos del modelo relacionado y le permita publicar directamente en el modelo único?

// EDIT – Esto es lo que estoy tratando de publicar

 $scope.doClick = function (event) { var test_data = { title: 'Event Test', content: 'Some test content here', location: 2, date: '2014-12-16T11:00:00Z' } // $resource.save() doesn't work? $http.post('/api/events/', test_data). success(function(data, status, headers, config) { console.log('sucess', status); }). error(function(data, status, headers, config) { console.log('error', status); }); } 

Entonces, cuando los serializadores son planos, puedo publicar todos estos campos. El campo de ubicación es el ID de una ubicación de la tabla de ubicaciones relacionadas. Cuando están nesteds, no puedo incluir el campo de ubicación en los datos de prueba.

Al establecer la opción de depth en el serializador, le está diciendo que haga una relación anidada en lugar de plana. En su mayor parte, los serializadores nesteds se deben considerar de solo lectura de manera predeterminada, ya que tienen errores en Django REST Framework 2.4 y hay mejores formas de manejarlos en 3.0.

Parece que desea una representación anidada al leer, pero una representación plana al escribir. Si bien esto no es recomendable, ya que significa que las solicitudes GET no coinciden con las solicitudes PUT, es posible hacerlo de una manera que haga felices a todos.

En Django REST Framework 3.0, puede intentar lo siguiente para obtener lo que desea:

 class LocationsSerializer(serializers.ModelSerializer): class Meta: model = Locations fields = ('title', 'address', ) class EventsSerializer(serializers.ModelSerializer): locations = LocationsSerializer(read_only=True) class Meta: model = Events fields = ('locations', ) class EventViewSet(viewsets.ModelViewSet): queryet = Event.objects.all() serializer_class = EventsSerializer def perform_create(self, serializer): serializer.save(locations=self.request.data['locations']) def perform_update(self, serializer): serializer.save(locations=self.request.data['locations']) 

Se creó un nuevo LocationsSerializer , que manejará la representación anidada de solo lectura del objeto Locations . Al reemplazar a perform_create y perform_update , podemos pasar el ID de ubicación que se pasó con el cuerpo de la solicitud, por lo que la ubicación aún se puede actualizar.

Además, debes evitar tener nombres de modelos que sean plurales. Es confuso cuando Events.locations es una sola ubicación, aunque Locations.events es una lista de eventos para la ubicación. Event.location y Location.events lee un poco más claramente, el administrador de Django los mostrará de manera razonable y los demás desarrolladores podrán comprender fácilmente cómo se configuran las relaciones.