【发布时间】:2019-04-01 10:51:54
【问题描述】:
TLDR;使用 Django Rest Framework,如何仅使用所述 M2M 字段的 ID/PK 对具有多对多关系字段的 API 资源进行 POST(应用程序/json 内容)?
我目前正在为一个使用 Django Rest Framework 的大学项目建模应用程序。以下模型代表应用程序的志愿者(我隐藏了一些小细节以避免污染代码)
class Volunteer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
state = models.CharField(max_length=2, choices=STATE_CHOICES)
city = models.CharField(max_length=255)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES, blank=True, null=True)
phone = models.CharField(max_length=13)
email = models.EmailField(max_length=100)
description = models.TextField(max_length=500)
photo = models.ImageField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
interest_areas = models.ManyToManyField(VolunteeringArea, blank=True)
class Meta:
verbose_name_plural = "Volunteers"
ordering = ("first_name", "last_name")
def __str__(self):
return self.first_name + ' ' + self.last_name
def get_absolute_url(self):
return reverse('volunteers:volunteer-detail', kwargs={'pk': self.id})
相应的序列化器如下所示:
class VolunteerSerializer(serializers.ModelSerializer):
interest_areas = VolunteeringAreaSerializer(many=True)
class Meta:
model = Volunteer
fields = ('id', 'first_name', 'last_name', 'phone', 'email', 'state', 'gender', 'interest_areas', 'city', 'description', 'photo')
read_only_fields = ('created_at', )
def to_representation(self, instance):
representation = super(VolunteerSerializer, self).to_representation(instance)
representation['interest_areas'] = VolunteeringAreaSerializer(instance.interest_areas.all(), many=True).data
return representation
您可能会注意到,每个志愿者都可能有许多相关领域归因于它(多对多领域)。以下模型表示它:
class VolunteeringArea(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(max_length=512)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = "VolunteeringAreas"
def __str__(self):
return self.title
def slug(self):
return slugify(self.title
)
而相应的序列化器是:
class VolunteeringAreaSerializer(serializers.ModelSerializer):
class Meta:
model = VolunteeringArea
fields = ('id', 'title', 'description')
read_only_fields = ('created_at', 'is_active')
我的问题是,当尝试通过提供感兴趣区域 ID 的 POST(应用程序/json)创建新志愿者时,我收到一条回复说我应该提供一个 dict,但应用程序却收到了一个 int。我意识到该应用程序期望包含来自interested_area 的所有字段的完整字典,但我只想提供 ID/PK 并且它会创建对象。
我一直在互联网上寻找几个小时,似乎我应该首先创建没有兴趣区域的对象,然后将它们添加到对象中。我试图在模块的views.py上定义一个create方法(与框架定义的原始create方法相同),但它似乎卡在了serializer.is_valid(),很可能表明提供的值在interested_area 字段无效。
def post(self, request, format=None):
return self.create(request)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_serializer(self, *args, **kwargs):
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
我的错误是什么,我该如何解决?
为方便起见,这是请求的正文内容,使用 Postman:
{
"interest_areas": [0,1],
"first_name":"NameOfThePerson",
"last_name":"LastNameOfThePerson",
"phone":"RandomCellphoneNumber",
"email":"randomemail@randomemail.com",
"gender":"Gender",
"state":"State",
"city":"City",
"description":"randomDescription"
}
提前感谢您的帮助!
【问题讨论】:
-
我的回答对你有帮助吗?
标签: python json django post django-rest-framework