Using Django rest
Below is how I had my serializer.py.
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('id', 'name', 'active', 'type')
Type is a flatview
I then changed it so 'type' was nested for each profile like this...
class TypeSerializer(serializers.ModelSerializer):
class Meta:
model = Type
fields = ('id', 'name', 'active')
class ProfileSerializer(serializers.ModelSerializer):
type = TypeSerializer()
class Meta:
model = Profile
fields = ('id', 'name', 'active', 'type'')
now this works perfect, but I can now only update 'type' when in profile detail it's now read-only.
How can I add type when creating a new profile and still keep this nested view?
I hope I have explained this clearly .
UPDATE:
Ok, I just read this:
Note: Nested serializers are only suitable for read-only representations, as there are cases where they would have ambiguous or non-obvious behavior if used when updating instances. For read-write representations you should always use a flat representation, by using one of the RelatedField subclasses.
So that makes sense. So I changed it to....
type = serializers.PrimaryKeyRelatedField()
That puts it back in the POST and work, but it's a shame, can I not represent 'type' with ID and the name so it makes more sense to the end user?
This is now supported (I am using version 2.3.6 but it might be introduced earlier). You can use it in the serializer direcly like this:
class SongSerializer(serializers.ModelSerializer):
class Meta:
model = Song
class AlbumSerializer(serializers.ModelSerializer):
songs = SongSerializer(many=True)
class Meta:
model = Album
Hope it helps :)
Full support of writable nested serializers is a work in progress, but in the mean time one solution is to override the create
method in the view in each case:
class FooListCreateView(ListCreateAPIView):
model = Foo
serializer_class = FooSerializer
def create(self, request, *args, **kwargs):
data=request.DATA
f = Foo.objects.create()
# ... create nested objects from request data ...
# ...
return Response(serializer.data,
status=status.HTTP_201_CREATED,
headers=headers)
Probably not ideal, but it works for me until the proper way comes along.
I had the same problem in django-rest-framework, and I have created a View for doing this real quick, you can find it in this gist: https://gist.github.com/edulix/5311365
Basic usage of CRUDManyToManyView is the following:
views.py
from models import Project
from serializers import TaskSerializer
from lib.crudmanytomanyview import CRUDManyToManyView
class ProjectTasks(CRUDManyToManyView):
model = Project
field_name = 'tasks'
serializer_class = TaskSerializer
urls.py
from django.conf.urls import patterns, url
import views
urlpatterns = patterns(
'',
url(r'^projects/(?P<pk>[0-9]+)/tasks/((?P<field_pk>[0-9]+)/)?$',
views.ProjectTasks.as_view()),
)
serializers.py
from rest_framework import serializers
from models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = ('id', 'name')
models.py
from django.db import models
class Task(models.Model):
name = models.CharField(max_length=140, blank=False, null=False)
class Project(models.Model):
name = models.CharField(max_length=140, blank=False, null=False)
tasks = models.ManyToManyField(Task, related_name='projects')
Then you can do things like:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With