-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Missing default value from ModelSerializer #2683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The default is set by the model, so the serializer can simply set use |
Thanks for your quick response. This is true but it's annoying to generate the documentation. I understand that funcionality-wise, this maybe useless as you pointed out, but for documentation it is not. Can you please reconsider it? I can't see any disadvantage. Thanks in advance. |
👍 on reopening this. I'm using a custom metadata class that produces JSON Schema. It would be very helpful to be able to set a default value, especially when using something like Angular Schema Form for form generation. |
I'd consider reopening this but only in the face of an example PR and solid proposal. Model defaults are model defaults. The serializer should omit the value and defer responsibility to the |
For what it's worth, DRF 2.x actually used the default values set on the model fields. DRF stopped using them as of 3.0.x. This actually bit me when upgrading our app, because we have some use cases where the serializer gets initialized with a null instance::
The same thing would happen if you deserialized data that is missing the field. On the one hand, it's sorta nice that the serializer reflects the data that was actually passed to it. On the other, it feels out of sync with the model; if we'd instantiated the model class with the same data, we'd see the default value. |
I've faced this issue as well. In my use case, it is related to |
Do you know why it was removed from DRF 3.0? I'm sure they had a good reason. To me it is surprising behaviour: from django.db import models
from rest_framework import serializers
class Foo(models.Model)
time_is_null = models.BooleanField(default=True, blank=True)
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
fields = '__all__'
print(FooSerializer().data) # {'time_is_null': False} <--- would expect True The serializer will initialise the time_is_null value as |
Another 👍 on reopening this. I'm facing a similar issue as this commenter: #2683 (comment) We're trying to instantiate a serializer with a subset of the overall data, run some operations based on that data + model defaults, and then save the final result. We found that we CAN get the "complete" data with default values — if we call try:
# initial serialization + save for complete data
serializer = MySerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
complete_data = serializer.data
# operate on complete data
updated_data = do_stuff(complete_data)
# save updated data
object = MyModel.objects.get(id=updated_data.get("id"))
serializer = MySerializer(object, data=updated_data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
except ValidationError:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
Its ridiculous to say
|
ok here's an even better solution for now
|
This is still frustrating. #2683 (comment) is a use case that hurts. I have a model with several fields that are unique together but have sensible defaults. Those defaults are not applied. Works just fine in pure Django however serializers are not happy. Like the Mixin suggestion above, the plan is to force the consumption of those defaults.....
|
I would be happy to review a PR addressing this issue |
@auvipy I would be happy to post a PR. Is my approach sensible? Or should #2683 (comment) be explored? It did not work for me but that could have been a mistake I made. |
I can't say anything definitive right now. I would like to discuss further on a PR where we can iterate over several approach. and of course with good amount of usecase examples as test cases |
Do forms not use the defaults from the models? Are serializers not similar to forms? If it makes sense for forms to use the defaults, especially when provided default objects for creation, why does it not make sense for serializers to do same. A solid example is when making a create object interface, and you wish to serialize a new "blank" object. |
In Django REST Framework (DRF), when a model field has a default value, the serializer does not automatically include this default value. Instead, the default is applied by the model during save operations. Example
The serializer:
Results in:
Why This Happens Customizing Serializer
This behavior is expected. Serializers validate input data, while models handle default values during save operations.
|
On a ModelSerializer specifically, this behavior is unexpected.
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
When creating a serializer from a model, the default value is not included in the serializer. I thought it was a bug and I was going to try to fix it and make a pull request, but I ran into the test suite and may be this is the expected behavior.
In the file
django-rest-framework/tests/test_model_serializer.py
, theFieldOptionsModel
has a field declared asdefault_field = models.IntegerField(default=0)
.In the test
TestRegularFieldMappings.test_field_options
, the expected serializer should containdefault_field = IntegerField(required=False)
, which does not include the default value of0
.I would expect to have
default_field = IntegerField(default=0)
(which would also imply required=False) ordefault_field = IntegerField(default=0, required=False)
Is this the expected behavior or a bug?
The text was updated successfully, but these errors were encountered: