Получаване на различни редове въз основа на определено поле от база данни в Django

Трябва да създам заявка в Django и се чудя дали това е възможно по някакъв начин (може да е наистина очевидно, но ми липсва...).

Имам нормална заявка Model.objects.filter(x=True)[:5], която може да върне резултати като този:

FirstName    LastName    Country
Bob           Jones        UK
Bill          Thompson     UK
David         Smith        USA

Трябва да взема само редове, които са различни въз основа на полето Country, нещо като Model.objects.filter(x=True).distinct('Country')[:5] би било идеално, но това не е възможно с Django.

Редовете, които искам заявката да грабне в крайна сметка, са:

FirstName    LastName    Country
Bob           Jones        UK
David         Smith        USA

Също така имам нужда заявката да използва същия ред, както е зададен в мета класа на модела (т.е. не мога да отменя подреждането по никакъв начин).

Как да направя това?

Благодаря много.


person Dx143    schedule 23.11.2009    source източник
comment
Имам нужда само от първите пет реда от DB.   -  person Dx143    schedule 23.11.2009
comment
Това е трудно, но не съм сигурен, че разбирам напълно въпроса. Искате ли първите пет реда, в които страната се отличава?   -  person jathanism    schedule 23.11.2009
comment
@S.Lott, нарязването на набор от заявки не го превръща в списък. Dx143 е прав, че това е начинът просто да получите първите 5 елемента от базата данни.   -  person Daniel Roseman    schedule 23.11.2009
comment
Изглежда, че има билет за това: code.djangoproject.com/ticket/6422   -  person shacker    schedule 04.02.2010


Отговори (3)


Не съм тествал това, но ми се струва, че dict трябва да свърши работата, въпреки че подреждането може да е изключено тогава:

d = {}
for x in Model.objects.all():
    d[x.country] = x

records_with_distinct_countries = d.values()
person extraneon    schedule 23.11.2009
comment
Същото нещо може да се извърши с улавяне на стойностите в set. - person jathanism; 23.11.2009
comment
Не точно. Страните могат да бъдат поставени в комплекта, тъй като са неизменни. Но моделите определено не са неизменни, така че не могат да бъдат в комплект. Ето защо използвам dict, неизменната държава като ключ и записа като стойност. Случва се да използвам dict ключовете като набор (което концептуално е), без да загубя записа. - person extraneon; 24.11.2009

Мисля, че @skrobul е на прав път, но малко встрани.

Не мисля, че ще можете да направите това с една заявка, защото методът distinct() добавя модификатора SELECT DISTINCT към заявката, който действа върху целия ред. Вероятно ще трябва да създадете списък с държави и след това да върнете ограничени QuerySets въз основа на повторение на този списък.

Нещо като това:

maxrows = 5
countries = set([x.country for x in Model.objects.all()])
rows = []
count = 0
for c in countries:
    if count >= maxrows:
        break

    try:
        rows.append(Model.objects.filter(country=c)[0])
    except Model.DoesNotExist:
        pass

    count += 1

Това е много общ пример, но дава желания резултат.

person jathanism    schedule 23.11.2009

Можете ли да публикувате необработения SQL, който връща това, което искате от изходната база данни? Имам предчувствие, че действителният проблем тук е структурата на заявката/данните...

person morrissimo    schedule 23.11.2009