Reputation: 219
My users can create one or more lists with items.
I'm using django REST-framework
and subclass the 'viewsets.ModelViewSet' to receive a json
object list_item
which has as a foreign key
: the list field.
Here is what I want to do:
Testcode (simplified):
test_posting_item_creates_list(self):
item = {
'name': "test",
# 'list': 1,
'user': self.user.id,
}
response = self.client.post('/api/listitems/',
json.dumps(item),
content_type="application/json")
self.assertEqual(response.status_code, 201, 'statuscode is 201 created')
This is my serializer
class ItemSerializer(serializers.ModelSerializer):
# this works for changing the list but a list field is required when posting
def validate(self, attrs):
if 'list' in attrs:
attrs['list'] = TodayList.objects.create()
class Meta:
model = TodayListItem
fields =('id',
'name',
'user',
'list',
)
With my validate
method I can change the list, to a different one so I tried:
if 'list' not in attrs:
but that doesnt work.
Is the Serializer the right place to "intercept" the post and create the list? How can I make a field optional?
Upvotes: 1
Views: 7202
Reputation: 6040
In your serializer you can mark your fields as not required by passing required
arguments as False
class UserResponse(ModelSerializer):
response = IntegerField()
meta_data = MetaDataSerializer(allow_null=True, required=False)
Upvotes: 2
Reputation: 3018
Based on Django REST framework manual
Field-level validation
You can specify custom field-level validation by adding .validate_ methods to your Serializer subclass. These are analogous to .clean_ methods on Django forms, but accept slightly different arguments.
They take a dictionary of deserialized attributes as a first argument, and the field name in that dictionary as a second argument (which will be either the name of the field or the value of the source argument to the field, if one was provided).
So, the Solution is to create a list validation method like this:
def validate_list(self, attrs, source):
"""
Check that the list is correct or not?
"""
if list not in attrs:
list_item = TodayList.objects.create()
list = list_item.id
return attrs
Another solution is in the model level, by overriding the save()
and check the list id.
def save(self, *args, **kwargs):
if self.list is None:
self.list = TodayList.objects.create()
super(TodayListItem, self).save(*args, **kwargs) # Call the "real" save() method.
Upvotes: 0