Python Django多对多模型DRF
我有以下模型结构:Python Django多对多模型DRF,python,django,django-models,django-rest-framework,django-orm,Python,Django,Django Models,Django Rest Framework,Django Orm,我有以下模型结构: class Project(models.Model): author = models.ManyToManyField(Account) name = models.CharField(max_length=40, default='NewBook') class Account(AbstractBaseUser): email = models.EmailField(unique=True) username = models.CharField(max
class Project(models.Model):
author = models.ManyToManyField(Account)
name = models.CharField(max_length=40, default='NewBook')
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
我的观点是这样的:
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.order_by('-name')
serializer_class = ProjectSerializer
def perform_create(self, serializer):
instance = serializer.save(author=self.request.user)
return super(ProjectViewSet, self).perform_create(serializer)
调用view函数后,将在数据库中创建一个分类器。但在那之后,我得到了以下错误:
TypeError:“帐户”对象不可编辑
在此行中引发错误:
instance = serializer.save(author=self.request.user)
有谁能帮我解决这个问题吗?在处理多个关系(m2m或反向FK)时,您需要设置
many=True
:
author = AccountSerializer(read_only=True, required=False, many=True)
由于Author字段是多对多字段,因此需要重写序列化程序上的create方法
def create(self, validated_data):
author = validated_data.pop(author, None)
project = Project.objects.save(validated_data)
if author:
project.author.add(author)
您可能还需要在序列化程序上设置更新方法,此处的行为可能比较棘手,因此请确保您进行了测试,并确保该行为符合您的预期。好的,我之前的回答可能是一个问题,但不是实际崩溃的根本原因 调用序列化程序时,可以设置:
instance = serializer.save(author=self.request.user)
但是,作者是ManyToManyField
,这意味着您应该将序列化程序称为:
instance = serializer.save(author=[self.request.user])
注意:您仍然需要序列化程序的作者字段中的many=True。请检查
您的型号.py
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
class Project(models.Model):
author = models.ManyToManyField(Account)
name = models.CharField(max_length=40, default='NewBook')
class ProjectSerializer(serializers.ModelSerializer):
author = AccountSerializer(read_only=True, required=False)
class Meta:
model = Project
fields = ('id', 'author', 'name')
read_only_fields = ('id')
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(ProjectSerializer, self).get_validation_exclusions()
return exclusions + ['author']
您的序列化程序.py
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
class Project(models.Model):
author = models.ManyToManyField(Account)
name = models.CharField(max_length=40, default='NewBook')
class ProjectSerializer(serializers.ModelSerializer):
author = AccountSerializer(read_only=True, required=False)
class Meta:
model = Project
fields = ('id', 'author', 'name')
read_only_fields = ('id')
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(ProjectSerializer, self).get_validation_exclusions()
return exclusions + ['author']
最后,您的视图.py是
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.order_by('-name')
serializer_class = ProjectSerializer
def perform_create(self, serializer):
instance = serializer.save(author=self.request.user)
return super(ProjectViewSet, self).perform_create(serializer)
这里有两个问题:
many=True
标志添加到序列化器字段
因此,您需要将many=True
添加到AccountSerializer
:
author = AccountSerializer(read_only=True, required=False, many=True)
create()
和/或update()
方法,以明确指定应如何保存子关系
因此,如果您查看示例和文档,似乎需要实现
create
或update
方法。您需要向我们展示完整的stacktrace,我们无法判断错误是如何发生的。这是完整的stacktrace@ShangWang,您的序列化程序是什么样子的?这是我的序列化程序@Linovia,谢谢,现在正在创建项目。另一个问题:如何向项目中添加作者?我必须在前端调用.PUT(..)吗?你可以在前端调用PATCH
方法,然后在序列化程序中编写update()
方法来处理这个问题。