Django удалить дубликаты после фильтрации из объектов модели - PullRequest
0 голосов
/ 09 мая 2020

У меня есть модель под названием Course , я пытался получить их список с помощью функции фильтрации. Теперь у каждого курса разные поля.

Моя модель курса:

class Course(models.Model):
    course_code = models.CharField(max_length=20)
    course_university = models.CharField(max_length=100)
    course_instructor = models.CharField(max_length=100)
    course_year = models.IntegerField(('year'), validators=[MinValueValidator(1984), MaxValueValidator(max_value_current_year())])
    course_likes = models.ManyToManyField(Profile, blank=True, related_name='course_likes')
    course_dislikes = models.ManyToManyField(Profile, blank=True, related_name='course_dislikes')
    course_reviews = models.ManyToManyField(Review, blank=True, related_name='course_reviews')

Я пытаюсь получить курсы для инструктора по имени "Smiths" в Оксфордском университете

courses = Course.objects.filter(course_instructor="smiths",course_university="university")

Как я могу удалить дубликаты с таким именем, например, показать тот, у которого последний год? Так, например, будет курс ABC123 профессором Smith в Оксфордском университете через лет 2017,2018,2019, ... как я могу вернуть только один из них? Я пробовал distinct(), но это не работает.

Есть ли способ сделать это? Или мне следует изменить всю структуру моей базы данных?

EDIT: Я пробовал это, но он все еще дает мне дубликаты:

course_dup = Course.objects.filter(course_instructor=par2,course_university=par1).values('course_instructor', 'course_university').annotate(course_year=Max('course_year'))
courses = Course.objects.filter(course_instructor__in=[c['course_instructor'] for c in course_dup], course_university__in=[c['course_university'] for c in course_dup])

Итак, для пояснения представьте себе, что это это следующие значения:

   course_code | course_instructor | course_year | course_university 

1. ABC123      | smith             | 2017        | Oxford
2. ABC123      | smith             | 2017        | Oxford
3. CDE123      | smith             | 2018        | Oxford
4. ADF123      | smith             | 2019        | Oxford
5. ABC123      | smith             | 2019        | Oxford

Я хочу вернуть только для примера 3,4,5 , поскольку 5 является последним с кодом курса ABC123 или даже запрос, который возвращает 1,3,4 , должен работать, поскольку 1 - это первое совпадение, соответствующее запросу. Как я могу этого добиться?

Ответы [ 2 ]

0 голосов
/ 09 мая 2020

Это исключает первое значение и удаляет остальные

courses = Course.objects.filter(course_instructor="smiths",course_university="university")
if len(courses) > 1:
    courses[1:].delete()
0 голосов
/ 09 мая 2020

Это решит вашу проблему

course_dup = Course.objects.filter(course_instructor="smiths",course_university="university").values('course_instructor', 'course_university').annotate(course_year=MAX('course_year'))

Edit :: Поскольку вы хотите установить запрос, после этого запроса вы можете запустить это

courses = Course.objects.annotate(combined_key=Concat('course_instructor', V('_'), 'course_university', V('_'), 'course_year',output_field=CharField())).filter(combined_key__in=["{}_{}_{}}".format(c['course_instructor'], c['course_university'], c['course_year']) for c in course_dup])

...