"<Model> with this <field> already exist" on PUT call - Django REST Framework -
i'm doing http put call update data of object nested relationship, , i'm met following error:
http 400 bad request
"attributechoice slug exists."
the reason why confusing because i'm doing http put
call , expect treat update
, not create
.
my models this:
class attribute(models.model): name = models.charfield(max_length=100) text_input = models.booleanfield(default=false) slug = models.slugfield(unique=true) class attributechoice(models.model): attribute = models.foreignkey(attribute) value = models.charfield(max_length=100) slug = models.slugfield(unique=true)
my serializers this:
class attributechoiceserializer(serializers.modelserializer): class meta: model = attributechoice fields = '__all__' extra_kwargs = {'id': {'read_only': false}} class attributeserializer(serializers.modelserializer): attributechoice_set = attributechoiceserializer(many=true) class meta: model = attribute fields = ('id', 'name', 'text_input', 'slug', 'attributechoice_set') def update(self, instance, validated_data): choice_data = validated_data.pop('attributechoice_set') choice in choice_data: # if id within call, update object matching id if 'id' in choice: try: choice_obj = attributechoice.objects.get(pk=choice['id']) choice_obj.value = choice['value'] choice_obj.slug = choice['slug'] choice_obj.attribute = instance # if id not found, create new object except attributechoice.doesnotexist: choice_obj = attributechoice(**choice) # if no id within call, create new object. else: choice_obj = attributechoice(**choice) choice_obj.save() return instance
debug: if remove update()
function, still same error. believe error reported when .is_valid()
called in viewset. it's not update()
causes it.
also, if remove attributechoice_set = attributechoiceserializer(many=true)
, include attributechoice_set
in fields = ()
, error disappears, need line rest of code work.
even through you're doing update, doesn't mean nested data updated.
you're saying want update top object.
in cases, you'll removing or creating new nested objects while updating top one.
therefore drf considers default nested objects creation. can work around explicitly removing unique constraint on nested serializer:
class attributechoiceserializer(serializers.modelserializer): class meta: model = attributechoice fields = '__all__' extra_kwargs = { 'id': {'read_only': false}, 'slug': {'validators': []}, }
Comments
Post a Comment