Reputation: 848
I have a form where the user can post a deal, and for that they can choose to either upload an image (x), or provide a link to an already uploaded one on the internet (y). So when either of the fields exists and is valid, I would like to dismiss the other field from validation. Here is a simplified Model:
class Deal(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='deals',
on_delete=models.CASCADE)
title = models.CharField(max_length=1024, blank=False, null=False)
slug = models.SlugField(max_length=1024, unique=True, blank=True)
poster = models.ImageField()
poster_url = models.CharField(max_length=1024, blank=True, null=True)
created = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
And here's my serializer:
class DealSerializer(serializers.ModelSerializer):
user = UserSerializer(many=False, read_only=True)
class Meta:
model = Deal
fields = '__all__'
def validate_poster_url(self, value):
poster = self.initial_data.get("poster")
if value == "" and poster == "":
# set to mutable
self.initial_data._mutable = True
self.initial_data.delete("poster")
raise serializers.ValidationError(
"Deal must either have a Poster or a Poster URL")
return value
def validate_poster(self, value):
poster_url = self.initial_data.get("poster_url")
if value != "":
if poster_url == "":
# set to mutable
self.initial_data._mutable = True
self.initial_data.delete("poster_url")
raise serializers.ValidationError(
"Deal must either have a Poster or a Poster URL")
return value
def create(self, validated_data):
deal, _ = Deal.objects.update_or_create(**validated_data)
return deal
When I submit for example a poster_url, the poster field still gets validated and I get a validation error:
poster: ["The submitted data was not a file. Check the encoding type on the form."]
I have tried to "delete" the required field from the initial_data as an attempt, but that wouldn't work, and I also tried to use the global validate()
, but it was never called. I would really appreciate any help. Thank you.
Upvotes: 1
Views: 183
Reputation: 9909
Well, Deal.poster
is not optional, so that's why Django complains. I don't think you can handle this on the serializer level. Take a look at Django - how to make ImageField/FileField optional?.
Upvotes: 1