Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
85 views
in Technique[技术] by (71.8m points)

How to convert for loop to ORM in python django

I have these models:

class Employee(models.Model):
id = models.AutoField(primary_key=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100, null=True, blank=True)
location = models.CharField(max_length=100, default='Helsinki')
experience_brief = fields.RichTextField(null=True, blank=True)
image = models.ImageField(upload_to='employees', blank=True, null=True)

class ParticipationLog(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
employee = models.ForeignKey(Employee, on_delete=models.PROTECT)
project = models.ForeignKey(Project, on_delete=models.PROTECT)
months = models.IntegerField(blank=True, null=True)
skills = models.ManyToManyField(Skill, blank=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
description = fields.RichTextField(blank=True, null=True)

class Project(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
description = fields.RichTextField(blank=True, null=True)
customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
start_date = models.DateField()
end_date = models.DateField(blank=True, null=True)
anders_project = models.BooleanField(default=True)
skills = models.ManyToManyField(Skill, blank=True)

I need to filter employees with their skills and experience (years) like this:

filter skill:[python][3y] => Filter people with 3 or more years in python

For any skill find projects that have that skill. Then the amount of experience is calculated from:

  • If that log has months field filled => Use that value
  • If participation has a start or end dates => count it from those
  • If nothing, just use the project's start date until this date.

I wrote for loop to filter them and it works well:

@staticmethod
def diff_month(d1, d2):
    return (d1.year - d2.year) * 12 + d1.month - d2.month

def get_queryset(self):
    experience = self.request.GET.get('experience')
    skills = self.request.GET.get('skills')
    queryset = Employee.objects.all()
    employee_ids = []
    filtered_experience = False
    if skills:
        skills = skills.split(',')
        queryset = queryset.distinct().filter(participationlog__skills__in=skills)
    if experience:
        filtered_experience = True
        for employee in queryset:
            sum_experience_m = 0
            for employee_participation_log in employee.participationlog_set.filter(skills__in=skills):
                
                if employee_participation_log.months:
                    sum_experience_m += employee_participation_log.months
                else:
                    if employee_participation_log.end_date:
                        end_date = employee_participation_log.end_date
                    elif employee_participation_log.project.end_date:
                        end_date = employee_participation_log.project.end_date
                    else:
                        end_date = datetime.today()
                    if employee_participation_log.start_date:
                        start_date = employee_participation_log.start_date
                    else:
                        start_date = employee_participation_log.project.start_date
                    time_difference = self.diff_month(end_date, start_date)
                    sum_experience_m += time_difference
                if not float(experience) >= sum_experience_m / 12:
                    employee_ids.append(employee.id)
    if filtered_experience:
        return Employee.objects.filter(pk__in=employee_ids)
    else:
        return queryset

But I need to use ORM Django to do that. Anyone know how can I convert my code and just use the filter in Django to do that?

question from:https://stackoverflow.com/questions/65940731/how-to-convert-for-loop-to-orm-in-python-django

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...