【问题标题】:How do create an object that has multiple objects in django rest framework via a POST method using class based views如何使用基于类的视图通过 POST 方法在 django rest 框架中创建具有多个对象的对象
【发布时间】:2018-09-25 21:02:58
【问题描述】:

我在我的模型中创建了一个 Employee 类。 Employee 类有多个 Foreign 键,例如 User、Contact、Skill 等。我希望在创建 Employee 时创建所有其他对象以及包括 User目的。在我看来,我已经实现了一个POST 方法,但我觉得我的代码太长了。如何制作单个 POST 来创建所有这些多个对象?使用Managers 的插图也不错。

class Employee(models.Model):
    """
    Model, which holds general information of an employee.

    """
    user = models.OneToOneField(settings.AUTH_USER_MODEL,
                                related_name='employees', null=True)

    company = models.ForeignKey(
        'hr.Company',
        verbose_name='Company',
        related_name='companies',
        null=True, blank=True,
    )
    hr_number = models.CharField(
        verbose_name='HR number',
        blank=True, null=True,
        max_length=20, unique=True
    )
    identification_number = models.CharField(
        verbose_name='ID Number',
        blank=True, null=True,
        max_length=20, unique=True
    )
    contract_type = models.ForeignKey(Contract)
    tax_id_number = models.CharField(
        max_length=20, null=True, verbose_name='Tax ID', blank=True, unique=True)
    skill = models.ForeignKey(Skill)
    # joining can be added in user  profile
    joining_date = models.DateField(null=True, verbose_name="Joining Date")
    job_title = models.ForeignKey(
        Job, related_name='job_titles', null=True, blank=True, help_text='Default Permission for different modules in Portal depends upon employee\'s Designation.')
    department = models.ForeignKey(
        Department, related_name='department', null=True, blank=True, on_delete=models.SET_NULL)
    is_manager = models.BooleanField(default=False)
    # leave_count = models.IntegerField(default=0)
    active = models.BooleanField(default=True)

在我看来,我已经实现了下面的POST 方法:

class AddEmployee(APIView):
    # permission_classes = (permissions.DjangoObjectPermissions,)
    # serializer_class = EmployeeSerializer
    """
{
    "user":null,
    "new_user":{
    "first_name":"John",
    "last_name":"Wane",
    "username":"Wai",
    "email":"jwane@gmail.com",
    "password":"123"
    },
    "company":1,
    "department":1,
    "identification_number":"234567",
    "hr_number":"GH/099/2017",
    "tax_id_number":"AEEEEEE",
    "joining_date":"2018-04-02",
    "job_title":null,
    "new_job":{
        "name":"Doctor",
        "min_salary":50000,
        "max_salary":50000

    }
}
    """

    def post(self, request, format=None):
        try:
            company = Company.objects.get(id=request.data['company'])

            department = Department.objects.get(id=request.data['department'])
            try:
                c_user = User.objects.get(id=request.data['user'])
            except:
                new_user = request.data['new_user']
                c_user = User.objects.create(first_name=new_user['first_name'],
                                             last_name=new_user['last_name'],
                                             username=new_user['username'],
                                             email=new_user['email'],
                                             password=new_user['password'])
            try:
                job_title = Job.objects.get(id=request.data['job_title'])
            except:
                new_job = request.data['new_job']
            if new_job:
                job_title = Job.objects.create(
                    name=new_job['name'],
                    min_salary=new_job['min_salary'],
                    max_salary=new_job['max_salary']
                )

            employee = Employee.objects.create(
                user=c_user,
                company=company,
                department=department,
                job_title=job_title,
                hr_number=request.data['hr_number'],
                identification_number=request.data['identification_number'],
                tax_id_number=request.data['tax_id_number'],
                joining_date=request.data['joining_date']

            )
        except Exception as e:
            print(e)
        return Response(status=status.HTTP_201_CREATED)

【问题讨论】:

    标签: django python-3.x django-rest-framework django-views


    【解决方案1】:

    DRF 不管理嵌套序列化程序或此类事情。也就是说,您可以使用 Model.objects.get_or_create

    简化代码

    示例:

    try:
       job_title = Job.objects.get(id=request.data['job_title'])
    except:
       new_job = request.data['new_job']
    if new_job:
       job_title = Job.objects.create(
           name=new_job['name'],
           min_salary=new_job['min_salary'],
           max_salary=new_job['max_salary']
       )
    
    # can be write with get_or_create:
    job_defaults = {
        'name': new_job['name'],
        'min_salary': new_job['min_salary'],
        'max_salary': new_job['max_salary'] 
    }
    Job.objects.get_or_create(name=new_job['name'],defaults=job_defaults)
    

    您也可以使用Model Serializer来管理过滤+验证+保存子对象

    例子:

    # serializers.py
    
    class JobSerializer(serializers.ModelSerializer):
        class Meta:
            model = Job
            fields = ('id', 'name', 'min_salary', 'max_salary')
    
    # inside views.py's  post method
    
    try:
       job_title = Job.objects.get(id=request.data['job_title'])
    except:
       JobSerializer(data=new_job).save()
    

    另见:

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 2016-04-23
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-11-19
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多