2

I have created an Employee class below in my models. The Employee class has multiple Foreign Keys such as User,Contact,Skill etc. I would like to make it possible that when I create an Employee all the other objects will be created plus including the User object. I have implemented a POST method in my view that does this but I feel like my code is too long. How do I make a single POST to create all these multiple objects? An illustration using Managers will be also nice.

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)

In my views I have have implemented the POST method below:

class AddEmployee(APIView):
    # permission_classes = (permissions.DjangoObjectPermissions,)
    # serializer_class = EmployeeSerializer
    """
{
    "user":null,
    "new_user":{
    "first_name":"John",
    "last_name":"Wane",
    "username":"Wai",
    "email":"[email protected]",
    "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 Answer 1

1

DRF do not manage nested serialiser or this kind of things. that said, you can simplify your code using Model.objects.get_or_create

example :

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)

You can also use Model Serializer to manage filtering + validating + save sub object

examples :

# 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()

see also:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.