I have a value named 'active' which defaults to 'True' in the Django model. I would like to not set this value and allow it to be created by the default action, however, somewhere in the Django REST Framework it is being set to 'False' before it gets to the validate methods in the Serializer. How can I prevent this action or at least trap it, so that I can set a non-existent 'active' value to 'True'?
I'm only posting the relevant code, this is a complex system and the complete code would be overwhelming. The status columns come from this abstract class model. As you can see only the active column is defaulted to True.
class StatusModelMixin(models.Model):
active = models.BooleanField(
verbose_name=_("Active"), default=True,
help_text=_("If checked the record is active."))
soft_delete = models.BooleanField(
verbose_name=_("Hide"), default=False,
help_text=_("If checked the record is removed from all queries."))
purge = models.BooleanField(
verbose_name=_("Purge"), default=False,
help_text=_("If checked the record will be deleted."))
class Meta:
abstract = True
def save(self, *args, **kwargs):
"""
Intercept the save and update the 'purge' and 'soft_delete' objects.
This save will not be called during bulk creates and updates, so the
logic below will need to be duplicated for each object in bulk
operations.
"""
if self.purge: self.soft_delete = True
if self.soft_delete: self.active = False
super(StatusModelMixin, self).save(*args, **kwargs)
This is but one of the serializer class' that are effected by the issue I am having. You can see some of my test code that didn't fix the issue.
class OrganizationSerializer(serializers.ModelSerializer):
user = serializers.HyperlinkedRelatedField(
view_name='user-detail', read_only=True)
uri = serializers.HyperlinkedIdentityField(
view_name='organization-detail')
#active = serializers.BooleanField(default=True, required=True)
class Meta:
model = Organization
fields = ('id', 'address_01', 'address_02', 'city', 'region',
'postal_code', 'country', 'phone', 'fax', 'active',
'soft_delete', 'purge', 'ctime', 'mtime', 'institution',
'user', 'uri')
exclude = ('purge',)
read_only_fields = ('id', 'ctime', 'mtime',)
depth = 0
#def validate(self, attrs):
# log.debug("attrs: %s", attrs)
# return attrs
Thanks
Okay so i have just tried, and really the model default is being ignored, even when you specify it in serializer. Seems like when the value is not sent explicitly it is being ignored.
I have looked around and found a bug report for this:
https://github.com/tomchristie/django-rest-framework/issues/1101.
Until this is one is fixed you can try this ugly hack in your viewset:
def get_serializer(self, *args, **kwargs):
# data may be None
data = kwargs['data']
if data is not None:
data = data.copy() # need to make copy because of immutable QueryDict
data.setdefault('active', True)
kwargs['data'] = data
return super(OrganizationViewSet, self).get_serializer(*args, **kwargs)