2010-06-15 5 views
9

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

Django models http://mipadi.cbstaff.com/images/misc/people_django.jpg

В каждом отношениях, A Person может иметь 0 или более предметов.

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

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

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

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

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

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

Каков наилучший способ сделать это с помощью Django?

+7

+1 для диаграммы классов в цветах Django! –

ответ

1

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

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]) 
+0

Принимая это как ответ. Я решил проблему пару дней назад, но в итоге сделал примерно то, что вы предложили. – mipadi

0

Вы изучали агрегацию Django для «группового поведения» как поведение?

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

+0

Да; строка кода, которую я дал в основном, группирует записи, она просто не делает желаемой фильтрации. – mipadi

0

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

How to combine 2 or more querysets in a Django view?

Смежные вопросы