Reputation: 749
I'm having trouble creating an "Estimate" resource. Basically, what I'm trying to achieve is to make a single API call to create an "Estimate" instance, which has 3 foreign keys, and would prefer to use ModelViewSet to take advantage of all methods that comes with using it(POST, GET, PUT, DELETE, PATCH).
example :
Make a single POST call with the following data : {user: , property: , estimate_type:, message: "test message"} /api/estimates/
I managed to configure the API to retrieve all the details that I need, with exception of the "User" object details, instead I only get the URL, but I guess that's ok, since I can fetch the User details on a separate call.
I'm a bit confused and like to understand what's the correct approach to achieve creating the "Estimate" instance with a single call. Should I be overriding the save method of "Estimate" class?
All suggestions are greatly appreciated.
Django==1.7.6 djangorestframework==3.1.0
These are my models :
class Property(models.Model):
user = models.ForeignKey(User)
address = models.CharField(max_length=100)
def __str__(self):
return self.address
class EstimateType(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Estimate(models.Model):
user = models.ForeignKey(User)
property = models.ForeignKey(Property)
estimate_type = models.ForeignKey(EstimateType)
message = models.TextField(max_length=144)
def __str__(self):
return "{} {}".format(self.user.username, self.property.address1)
These are the serializers :
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('pk','username', 'email','first_name', 'last_name', 'is_staff')
class PropertySerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = Property
fields = ('pk','address','user')
class EstimateTypeSerializer(serializers.ModelSerializer):
class Meta:
model = EstimateType
fields = ('pk', 'name')
class EstimateSerializer(serializers.HyperlinkedModelSerializer):
property = PropertySerializer()
service = EstimateTypeSerializer()
class Meta:
model = Estimate
fields = ('pk','user','property','service', 'message')
The ViewSets:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class PropertyViewSet(viewsets.ModelViewSet):
queryset = Property.objects.all()
serializer_class = PropertySerializer
class EstimateTypeViewSet(viewsets.ModelViewSet):
queryset = EstimateType.objects.all()
serializer_class = EstimateTypeSerializer
class EstimateViewSet(viewsets.ModelViewSet):
serializer_class = EstimateSerializer
def get_queryset(self):
queryset = Estimate.objects.filter(user=self.request.user)
return queryset
Sending GET request to /api/estimate/
Retrieves the following :
[
{
"pk": 3,
"user": "http://localhost:8000/users/2/",
"property": {
"pk": 3,
"address": “123 Fake street",
"user": {
"pk": 2,
"username": “admin”,
"email": “[email protected]”,
"first_name": “Foo”,
"last_name": “Bar”,
"is_staff": true
}
},
“estimate_type”: {
"pk": 1,
"name": “basic”
},
"message": "Lorem Ipsum is simply dummy text of the printing and typesetting \n”
}
]
Upvotes: 6
Views: 10321
Reputation: 7778
To create a new Estimate linked to other existing records you would only need to send an object like this, with only the primary keys identifying the related objects:
{
"user": <user pk>,
"property": <property pk>,
"estimate_type": <estimate type pk>,
"message": "foo bar"
}
Writing to nested serializers - as you do - was not supported by restframework 2.x.
Have a look at how to create a writable RelatedField class: http://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields
Upvotes: 2