-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
3.15 is raising required error on model nullable fields #9378
Comments
Could you provide a code sample of your model, serializer and data for checking? |
class Foo(...):
...
value = models.IntegerField(null=True)
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
fields = '__all__'
serializer = FooSerializer(data=data) # This data does not have the "value" field
serializer.is_valid()
saved_data = serializer.save() Raises this error |
The The real issue would be how did that ever worked without a default in the first place? Usually a nullable field which is not required in forms is defined as: class Foo(...):
...
value = models.IntegerField(null=True, default=None, blank=True) |
I'm using a django v3.y.z for now, don't know if that's the problem. |
It is not documented nor in the codebase of django such behaviour for null or default. Django and the majority of DBMS does not suppose the default based on the assumption that a field is nullable. I can only guess that there is something else which is providing a value for those fields in your project (a middleware? the frontend? custom views? custom serializers? custom base models?). |
I don't think so, what I have it's pretty standard. |
Can you try your view with the @api_view(['GET','POST'])
def person(request):
if request.method == 'GET':
objs = Person.objects.all()
serializer = PeopleSerialiser(objs, many = True)
serializer.is_valid(raise_exception=True)
return Response(serializer.data) |
Ok, I apologize because the example that I posted was not complete, it was missing a uniqueConstraint 😅, I think its the same case as #9410 I've created a new project with your example to validate this. Modelsclass Color(models.Model):
color_name = models.CharField(max_length=100)
class Meta:
verbose_name = "Color"
verbose_name_plural = "Colors"
ordering = ('id',)
class Person(models.Model):
name = models.CharField(max_length=100)
lastname = models.CharField(max_length=100, null=True)
age = models.IntegerField(null=True)
color = models.ForeignKey(Color, on_delete=models.CASCADE, related_name='color', null=True)
class Meta:
verbose_name = "Person"
verbose_name_plural = "Persons"
ordering = ('id',)
constraints = [models.UniqueConstraint(name='unique_constraint', fields=('color', 'age'), )] Serializerclass ColorSerializer(serializers.ModelSerializer):
class Meta:
model = Color
fields = '__all__'
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = "__all__" Viewsetclass DRFBugViewset(viewsets.ModelViewSet):
serializer_class = PersonSerializer With DRF 3.14.0With DRF 3.15.1 |
I am facing the same issue as @Enorio |
If everyone here is having this issue when there are |
So basically I have to set a |
Ended up doing this from django_json_api.rest_framework import ModelSerializer
class LegacyDRFModelSerializer(ModelSerializer):
def get_validators(self):
# If the validators have been declared explicitly then use that.
validators = getattr(getattr(self, "Meta", None), "validators", None)
if validators is not None:
return list(validators)
# Otherwise use the default set of validators.
return self.get_unique_for_date_validators() Then using |
I tried to take the example from @Enorio earlier and I can reporduce the problem. However, if I change it as follows (which I think means the same thing, from Django perspective): class Color(models.Model):
color_name = models.CharField(max_length=100)
class Person(models.Model):
name = models.CharField(max_length=100)
lastname = models.CharField(max_length=100, null=True)
age = models.IntegerField(null=True)
color = models.ForeignKey(Color, on_delete=models.CASCADE, related_name='color', null=True)
class Meta:
- constraints = [models.UniqueConstraint(name='unique_constraint', fields=('color', 'age'))]
+ unique_together = ('color', 'age') Then it fails on both 3.14 and 3.15: From what I can tell, it's a change of behaviour due to adding support for a newer Django syntax. |
According to docs unique_together can be deprecated later and it is recommended to use constraints:
|
Yes, preceisely. They were designed as a more powerful replacement, and DRF handles constraints the same way as unique_together. |
Except it doesn't support conditional constraints + cases where field is set just before save or based on other data not in request (i.e. defined in Workaround for this now is to add in
So had to turn off as DRF does NOT handles constraints the same way. |
Yes I agree conditional contraints aren't well supported, and I think there is another more appropriate issue for that case (#9358). The cases reported so far in here aren't making use of conditional constraints however, and without conditions I was only saying that the behaviour is consistent with DRF 3.14 |
I have a model with nullable fields. Upgrading from 3.14 to 3.15 I'm getting this error:
AssertionError: You cannot call .save() on a serializer with invalid data.
When I print the
serializer.errors
afterserializer.is_valid()
, it says those fields are required. Is it possible that this is a bug, or do I have to manually override the field in the serializer to have therequired=False
kwarg?The text was updated successfully, but these errors were encountered: