【问题标题】:how to create three tables in nested-serializer objects using django rest framework如何使用 django rest 框架在嵌套序列化器对象中创建三个表
【发布时间】:2022-06-25 20:33:12
【问题描述】:

我正在尝试在 Django Rest Framework 中创建三个模型嵌套对象。

models.py:

class Project(models.Model):
    project_id = models.AutoField(primary_key=True, unique=True)
    project_name = models.CharField(max_length=100)

class ProjectSite(models.Model):
    site_id = models.AutoField(primary_key=True, unique=True)
    site_name = models.CharField(max_length=200,name='project_site_name')
    project_id = models.ForeignKey(Project, on_delete=models.CASCADE, blank=True, null=True, 
    related_name="projectid")

class Assignment(models.Model):
    assignment_id = models.AutoField(primary_key=True)
    assignment_name = models.CharField(max_length=150)
    site_id = models.ForeignKey(ProjectSite,related_name="projectsiteidkey", on_delete=models.CASCADE)
    assigned_to_id = models.ForeignKey('auth.User',related_name="assignedtoidfkey",on_delete=models.CASCADE)

serializer.py:

class ProjectSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Project
        fields = '__all__'
class ProjectSiteSerializer(serializers.ModelSerializer):
  
    class Meta:
        model = ProjectSite
        fields = '__all__'

class AssignedUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = Assignment
        fields = '__all__'

class CreateNewProjetSerial(serializers.ModelSerializer):
    site_name = ProjectSiteSerializer(many=True)
    assigned_to_id = AssignedUserSerializer(many=True)
    class Meta:
        model = Project
        fields = ['site_name','project_name','assigned_to_id']
   
    def create(self, validated_data):
        site_name = validated_data.pop('site_name')
        assigned_to_id = validated_data.pop('assigned_to_id')
        
        projects = Project.objects.create(**validated_data)
  
        for i in site_name:
            ProjectSite.objects.create(site_name=projects, **i)
            
            
        for j in assigned_to_id:    
            Assignment.objects.create(assigned_to_id=projects, **j)
  
        return projects 

view.py:

class MultieCreateAPIView(generics.CreateAPIView):
  queryset = Project.objects.all()
  serializer_class = CreateNewProjetSerial

我想发布一个这样的 JSON 对象:

{
"site_name": [{"site_name": "site1"}, {"site_name": "site2"}],
"project_name": "test_project",
"assigned_to_id": [{"assigned_to_id":2}, {"assigned_to_id":3}]
}

当我尝试发布此内容时,出现“无法分配“”错误:“Assignment.assigned_to_id”必须是“用户”实例”。

【问题讨论】:

  • Assignment模型中的site_id字段是ProjectSite模型的外键是否正确?
  • 是的,没错
  • 您想使用上传的站点名称和 Assignment 对象创建两个 ProjectSite 对象。而Assignment 对象将需要ProjectSite 数据作为外键。但你没有提到这一点。关于哪一个将是新创建的Assignmentsite_id
  • 对不起,我没看懂,请您更改模型。
  • 看,Assignment 模型有 ProjectSite 外键,对吧?

标签: python django django-models django-rest-framework django-serializer


【解决方案1】:

首先,您不需要设置 primary_key 字段,因为 django 会为您完成。所以你最好分别从3个模型中删除project_idsite_idassignment_id字段。 CreateNewProjetSerial 中存在一些错误。 site_nameassigned_to_id 字段应为read_only,如果无法与相关对象一起上传,则需要附加字段才能接收您的有效负载。

class CreateNewProjetSerial(serializers.ModelSerializer):
    site_name = ProjectSiteSerializer(many=True, read_only = True)
    assigned_to_id = AssignedUserSerializer(many=True, read_only = True)
    site_names = serializers.ListField(
        child = serializers.CharField(), write_only = True)
    user_ids = serializers.ListField(
        child = serializers.IntegerField(), write_only = True)

    class Meta:
        model = Project
        fields = ['site_name','project_name','assigned_to_id', 'site_names', 'user_ids']
   
    def create(self, validated_data):
        site_names = validated_data.pop('site_names')
        user_ids = validated_data.pop('user_ids')
        
        new_project = Project.objects.create(**validated_data)
  
        for site_name in site_names:
            new_project_site = ProjectSite.objects.create(project_id=new_project, site_name=site_name)            
            
            for user_id in user_ids:    
                Assignment.objects.create(assigned_to_id__id=user_id, site_id=new_project_site)
  
        return new_project

在前端,请像下面这样上传。

{
    "site_names": ["site1", "site2"],
    "project_name": "test_project",
    "user_ids": [2, 3]
}

【讨论】:

  • 这里我们只能返回project_name,如果我想返回'site_id',如何在response中返回project_name、site_id
  • 但是一个项目有很多站点,对吧?你想获取 id 列表吗?
  • 对,站点ID列表
  • 请检查我提出的与同一问题相关的这个问题stackoverflow.com/questions/72620746/…
猜你喜欢
  • 2020-04-11
  • 1970-01-01
  • 2013-05-05
  • 2019-06-14
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 2022-06-14
  • 2020-07-07
相关资源
最近更新 更多