如何使用基于类的视图通过POST方法在django rest框架中创建具有多个对象的对象

时间:2018-04-16 07:42:42

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

我在模型中创建了一个Employee类。 Employee课程有多个Foreign个关键字,例如UserContactSkill等。我想在我创建一个全部员工时可能将创建其他对象以及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)

1 个答案:

答案 0 :(得分: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()