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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…