Geo*_*nko 6 python django rest many-to-many django-rest-framework
我正在为我的Django应用程序编写REST API,并且无法获得POST请求以在一个模型上工作.这是有问题的模型:
class ProjectNode(models.Model):
name = models.CharField(max_length=60)
place = models.CharField(max_length=150)
time_spent = models.BigIntegerField()
parent_project = models.ForeignKey(Project, related_name='tasks')
workers = models.ManyToManyField(User, related_name='tasks_can_do')
def __str__(self):
return self.name
Run Code Online (Sandbox Code Playgroud)
该User模型目前只占据一个name领域.这是我的序列化器ProjectNode:
class ProjectNodeSerializer(serializers.ModelSerializer):
class Meta:
model = ProjectNode
fields = ('id', 'name', 'place', 'time_spent', 'workers',)
Run Code Online (Sandbox Code Playgroud)
这是API视图(来自views.py):
class WebProjectNodeListView(generics.ListCreateAPIView):
queryset = ProjectNode.objects.all()
serializer_class = ProjectNodeSerializer
def pre_save(self, obj):
obj.parent_project = Project.objects.get(pk=self.request.DATA['parent_project'])
for worker_pk in self.request.DATA['workers']:
obj.workers.add(User.objects.get(pk=worker_pk))
obj.final_worker = User.objects.get(pk=self.request.DATA['final_workers'])
Run Code Online (Sandbox Code Playgroud)
我昨天尝试了一个更简单的版本,它只有ProjectForeignKey关系,它似乎工作,所以我认为使用add也会工作,但我在测试API时遇到错误httpie(我已经添加了一些用户和项目,我相信我的ID正确了.)这是请求:
http POST :8000/api/tasks/ name="newtask" place="home" time_spent:=50 parent_project:=1 workers:=[1]
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
"<ProjectNode: newtask>" needs to have a value for field "projectnode" before this many-to-many relationship can be used.
Run Code Online (Sandbox Code Playgroud)
回溯也指向这行代码:
obj.workers.add(User.objects.get(id=worker_pk))
Run Code Online (Sandbox Code Playgroud)
现在,我觉得这是因为我在数据库中创建User对象之前尝试更新对象上的关系ProjectNode,但我不知道如何解决这个问题?
小智 3
DRF 无法创建嵌套序列化器对象或多对多字段的模型。因此有必要在创建 ProjectNode 之前重写 Serializer 创建方法并创建/获取 M2M 模型。尝试create(self, validated_data)在序列化器中重写并使用此方法中的数据。
例子:
我的模型项目与 ProjectImages 具有 M2M 关系。在 ProjectSerializer 中,我重写了这样的创建方法。
def create(self, validated_data):
try:
# Remove nested and M2m relationships from validated_data
images = validated_data.pop('projectimage_set') if 'projectimage_set' in validated_data else []
# Create project model
instance = Project(**validated_data)
if status:
instance.set_status(status)
project = instance.save()
# Create relations
for image in images:
ProjectImage.objects.create(project=project, **image)
except exceptions.ValidationError as e:
errors_messages = e.error_dict if hasattr(e, 'error_dict') else e.error_list
raise serializers.ValidationError(errors_messages)
return project
Run Code Online (Sandbox Code Playgroud)
希望这有帮助!
| 归档时间: |
|
| 查看次数: |
2274 次 |
| 最近记录: |