Как я могу отфильтровать эти записи Django?

У меня есть ряд моделей Django как показано в следующей схеме (названия обратных отношений показывают в желтых пузырях):

Django models
(источник: cbstaff.com)

В каждых отношениях, a Person может иметь 0 или больше из объектов.

Кроме того, slug поле (к сожалению), не уникально; несколько Person записи могут иметь те же поля краткого заголовка. По существу эти записи являются дубликатами.

Я хочу получить список всех записей, которые соответствуют следующим критериям: Все дублирующиеся записи (то есть, имея тот же краткий заголовок) по крайней мере с одним Entry ИЛИ по крайней мере один Audio ИЛИ по крайней мере один Episode ИЛИ по крайней мере один Article.

До сих пор у меня есть следующий запрос:

Person.objects.values('slug').annotate(num_records=Count('slug')).filter(num_records__gt=1)

Это группирует все записи slug, затем добавляет a num_records атрибут, который говорит, сколько записей имеет тот краткий заголовок, но дополнительная фильтрация не выполняется (и я даже не знаю, работало ли это правильно так или иначе, с тех пор, учитывая ряд дублирующихся записей, можно иметь, например, и Entry и другой может иметь Article).

Короче говоря я хочу найти все дублирующиеся записи и свернуть их, наряду с их связанными моделями, в одну запись.

Что лучший способ состоит в том, чтобы сделать это с Django?

9
задан Glorfindel 29 July 2019 в 19:05
поделиться

3 ответа

Я бы сделал это в нескольких запросах. Первый - это ваш список дубликатов, который у вас есть:

dupes = [p['slug'] for p in Person.objects.values('slug').annotate(num_records=Count('slug')).filter(num_records__gt=1)]

Затем я бы перебрал их и для каждого решил, какие из них оставить (примите произвольное решение - выберите первый). Затем для всех других первичных ключей просто обновите все другие объекты, чтобы они указывали на первичный ключ, который вы выбрали:

for slug in dupes:
    pks = [p.id for p in Person.objects.filter(slug=slug)]
    for pk in pks[1:]:
        Audio.objects.filter(person=pk).update(person=pks[0])
        Author.objects.filter(person=pk).update(person=pks[0])
        Episode.objects.filter(person=pk).update(person=pks[0])
        Entry.objects.filter(person=pk).update(person=pks[0])
1
ответ дан 5 December 2019 в 02:27
поделиться

Вы смотрели на агрегацию Django для 'group by', как поведение?

http://docs.djangoproject.com/en/dev/topics/db/aggregation/

0
ответ дан 5 December 2019 в 02:27
поделиться

Я не уверен, что объединение фильтров в цепочку поможет вам достичь желаемого результата, поскольку будут записи Person, в которых есть два или более типов артефактов с их названием. Посмотрите на предыдущий вопрос на StackOverflow и ответ на него, который, я думаю, поможет вам объединить четыре запроса в один QuerySet так, как вы хотите:

Как объединить 2 или более наборов запросов в представлении Django?

0
ответ дан 5 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: