英文:
Django Rest Framework UpdateAPIView is saying a field is required but the field is there
问题
The error you're encountering seems to be related to the campaign
field in your BigAd
model. It's expecting a campaign object, but you're providing a string value, which is causing the error.
You mentioned that it doesn't give you the same error for the audience
field, which suggests that the audience
field might be set up differently, possibly allowing a string value.
To resolve this issue, you should make sure that the campaign
field in your request data is a valid campaign object, not just its ID as a string. You may need to change the way you pass the campaign
value in your request data to provide a valid campaign object.
If you continue to face issues, please check your serializer and view logic to ensure that the campaign
field is being handled correctly in the update process.
英文:
I have this model that represents an Ad:
class BigAd(models.Model):
DA = 'DA'
WE = 'WE'
MO = 'MO'
INTERVAL = [
(DA, 'Day'),
(WE, 'Week'),
(MO, 'Month'),
]
IM = 'IM'
VI = 'VI'
TYPES = [
(IM, 'Image'),
(VI, 'Video'),
]
title = models.CharField(max_length=50, default=None)
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
audience = models.ForeignKey(AdAudience, on_delete=models.CASCADE, default=None)
active = models.BooleanField(default=False)
body = models.TextField(max_length=255, null=True, blank=True)
ad_image = models.FileField(upload_to=bigad_directory_path, null=True, blank=True)
ad_type = models.CharField(max_length=2, choices=TYPES, default=IM)
big_image = models.FileField(upload_to=bigad_directory_path, null=True, blank=True)
video = models.FileField(upload_to=bigad_video_path, null=True, blank=True)
link = models.URLField(max_length=256, null=True, blank=True)
budget_interval = models.CharField(max_length=2, choices=INTERVAL, default=DA)
budget = models.DecimalField(max_digits=30, decimal_places=0, default=200)
lowest_bid = models.DecimalField(max_digits=20, decimal_places=2)
highest_bid = models.DecimalField(max_digits=20, decimal_places=2)
includes_products = models.BooleanField(default=False)
product_list = ArrayField(models.IntegerField(), null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")
class Meta:
verbose_name = "big ad"
verbose_name_plural = "big ads"
db_table = "big_ads"
ordering = ["created_at"]
def __str__(self):
return self.title
def get_absolute_url(self):
return self.slug
and this serializer for serializing the data:
class BigAdSerializer(serializers.ModelSerializer):
campaign = ShortCampaignSerializer()
class Meta:
model = BigAd
fields = [
"id",
"title",
"campaign",
"audience",
"ad_image",
"ad_type",
"big_image",
"active",
"body",
"video",
"link",
"budget_interval",
"budget",
"lowest_bid",
"highest_bid",
"user",
"includes_products",
"product_list",
"active",
"created_at",
"updated_at",
]
and this view for processing the data:
class UpdateBigAd(generics.UpdateAPIView):
permission_classes = [IsAuthenticated]
serializer_class = AdSerializer
def get_queryset(self):
id = self.kwargs["pk"]
return BigAd.objects.all().filter(id=id)
I am trying to update the ad model but I get an error saying campaign is required but the data is there and campaign has a value. Here is the data in the backend received:
(Pdb) print(request.data)
<QueryDict: {'active': ['on'], 'title': ['First Big AD'], 'campaign': ['20'], 'audience': ['10'], 'body': ['This is the first bog ad'], 'ad_image': [''], 'big_image': [''], 'link': ['https://post.com'], 'budget_interval': ['DA'], 'budget': ['200'], 'lowest_bid': ['10.00'], 'highest_bid': ['20']}>
I thought it could be that because campaign value is a string but then it would give me the same error for 'audience' which it doesn't. It also cannot be that it requires and object because then again it would give me the same error for audience.
Why then am I getting this error please?
答案1
得分: 0
你定义了campaign = ShortCampaignSerializer()
,所以你的BigAdSerializer
期望的是一个对象而不是一个ID。请查看DRF文档中有关嵌套序列化器的部分。
我建议你在读取和写入操作时使用两个不同的序列化器:
class BigAdWriteSerializer(serializers.ModelSerializer):
...
class BigAdReadSerializer(BigAdWriteSerializer):
campaign = ShortCampaignSerializer()
然后,你需要覆盖你的更新视图方法,使用BigAdWriteSerializer
来写入数据,然后使用BigAdReadSerializer
来返回数据。
英文:
As you defined campaign = ShortCampaignSerializer()
your BigAdSerializer
expects an object not an ID. Have a look to DRF documentation regarding nested serializers.
I suggest that you use two differents serializers for read and write operations :
class BigAdWriteSerializer(serializers.ModelSerializer):
...
class BigAdReadSerializer(BigAdWriteSerializer):
campaign = ShortCampaignSerializer()
You then need to override you update view method to use BigAdWriteSerializer
to write data and then use BigAdReadSerializer
to return data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论