You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
3.15 added support for unique constraint validators in serializers: #7438
This unfortunately breaks when it comes to list serializers. It could make sense these not to run for list serializers if it's difficult to do so in an efficient manner without an O(N) query, and document that fact.
Reproducible Example
fromdjango.dbimportmodelsfromdjango.db.modelsimportUniqueConstraint, Qfromrest_frameworkimportserializersclassPet(models.Model):
name=models.CharField(max_length=100)
animal_type=models.CharField(max_length=100)
can_fly=models.BooleanField(null=True)
classMeta:
constraints= [
UniqueConstraint(
fields=["name", "animal_type"],
name="unique_pet",
)
]
classPetSerializer(serializers.ModelSerializer):
classMeta:
model=Petfields= ('name', 'animal_type', 'can_fly')
classPetListSerializer(serializers.ListSerializer):
child=PetSerializer()
defcreate(self, validated_data):
pets= [Pet(**item) foriteminvalidated_data]
returnPet.objects.bulk_create(pets)
instances=Pet.objects.all()
new_data= [
{"name": "Polly", "animal_type": "Parrot", "can_fly": True},
{"name": "Penguin", "animal_type": "Bird", "can_fly": False},
]
serializer=PetListSerializer(instances, data=new_data, many=True)
ifserializer.is_valid(raise_exception=True):
serializer.save() # This will create all pets in a single query
Running this will yield
AttributeError: 'BaseQuerySet' object has no attribute 'pk'
The text was updated successfully, but these errors were encountered:
Hi @max-muoto . I'm not sure to understand why you are trying to introduce PetListSerializer. It's DRF job to use ListSerializer once you will use PetSerializer with many=True. Also, if your intent is to create new pets in bulk ops, you haven't to pass instance to PetSerializer. Just data.
Your code could look like
# pet/models.pyfromdjango.dbimportmodelsfromdjango.db.modelsimportUniqueConstraintclassPet(models.Model):
name=models.CharField(max_length=100)
animal_type=models.CharField(max_length=100)
can_fly=models.BooleanField(null=True)
classMeta:
constraints= [
UniqueConstraint(
fields=["name", "animal_type"],
name="unique_pet",
)
]
# pet/serializers.pyfromrest_frameworkimportserializersfrompet.modelsimportPetclassPetSerializer(serializers.ModelSerializer):
classMeta:
model=Petfields= ("name", "animal_type", "can_fly")
# in your view, you have to writes=PetSerializer(data=[{"name":"Bob", "animal_type":"mammal", "can_fly":False}, {"name":"Drake", "animal_type": "not mamal"}], many=True)
s.is_valid()
s.save() # pets are created here# if you try to create same entries again s=PetSerializer(data=[{"name":"Bob", "animal_type":"mammal", "can_fly":False}, {"name":"Drake", "animal_type": "not mamal"}], many=True)
s.is_valid() # Falses.errors# [{'non_field_errors': [ErrorDetail(string='The fields name, animal_type must make a unique set.', code='unique')]}, {'non_field_errors': [ErrorDetail(string='The fields name, animal_type must make a unique set.', code='unique')]}]
Checklist
3.15 added support for unique constraint validators in serializers: #7438
This unfortunately breaks when it comes to list serializers. It could make sense these not to run for list serializers if it's difficult to do so in an efficient manner without an O(N) query, and document that fact.
Reproducible Example
Running this will yield
The text was updated successfully, but these errors were encountered: