Набор запросов Django, который возвращает все неназначенные fks - PullRequest
2 голосов
/ 20 января 2010

У меня есть 2 модели с отношением 1-1 (по существу, пул ресурсов). Для примера кода я просто буду использовать гайки и болты. Там будет намного больше гаек (доступных ресурсов), чем болтов (для каждого потребуется 1 гайка). Однако, если гайку можно назначить только одному болту.

Ограничение достаточно просто установить с помощью уникального именованного параметра True для метода ForeignKey.

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

Мне известен атрибут fields класса ModelForm, но я не могу найти фильтр набора запросов, который адекватно решает проблему. Вот пример кода моей проблемы:

from django.db import models
from django.forms import ModelForm

# Create your models here.

class Nut(models.Model):
    size = models.CharField()

class Bolt(models.Model):
    size = models.CharField()
    nut = models.ForeignKey( Nut, unique=True )

class BoltForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(BoltForm, self).__init__(*args, **kwargs)
        self.fields['nut'].queryset = # All unassigned nuts

Ответы [ 2 ]

4 голосов
/ 21 января 2010

Попробуйте это:

self.fields['nut'].queryset = Nut.objects.exclude(
    pk__in=Bolt.objects.values('nut').query)

Обновление

Из трех выражений, генерирующих один и тот же SQL-запрос:

pk__in=Bolt.objects.values('nut')
pk__in=Bolt.objects.values_list('nut')
pk__in=Bolt.objects.values('nut').query

Я бы выбрал последний как наиболее простой (хотя в двух других случаях список и dict фактически не создаются: django «понимает» намерение без явного упоминания .query)

Также рассмотрите ответ Даниэля Роземана. Это другой подход к тому же.

1 голос
/ 21 января 2010
Nut.objects.filter(bolt=None)
...