2013-07-20 2 views
4

У меня есть моделиDjango модель отношение

class Event(models.Model): 
    name = models.CharField(max_length = 50) 

class DriverClass(models.Model): 
    name = models.CharField(max_length = 20) 
    event = models.ForeignKey(Event) 

class Driver(models.Model): 
    name = models.CharField(max_length = 50) 
    event = models.ForeignKey(Event) 
    driverclass = models.ForeignKey(DriverClass) 

Событие должны иметь определенное количество DriverClass эсов для Driver на выбор. Проблема в том, что Driver подключен только к DriverClass и Event, поэтому, когда я выбираю DriverClass для драйвера в django admin, я могу выбрать из всех DriverClass es. Я не уверен, есть ли что-то, что я могу изменить в своей модели, чтобы выполнить то, что я хочу, или мне нужно только изменить класс Driver s ModelAdmin, чтобы отображать только правильные события. Какая правильная процедура?

+0

Каков критерий фильтра для «Драйвера» на «DriverClass»? – karthikr

+0

Драйвер связан с одним событием, а затем с драйверами класса Event. – Martol1ni

+1

Я считаю, что ваша модель плохо построена. Смотрите так: у вас есть «Событие», и на мероприятии может быть много «DriverClass». Хорошо. Таким образом, «DriverClass» уже связан с событием, и, следовательно, «драйвер», связанный с определенным «DriverClass», уже подключен к событию, не так ли? Я до сих пор не понимаю, чего вы хотите. –

ответ

4

Вы должны указать пользовательские ModelForm, который изменяет QuerySet данного поля driverclass и добавить его к вашему ModelAdmin:

class DriverForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(DriverForm, self).__init__(*args, **kwargs) 
     if self.instance.event: 
      # this form has an event specified in either instance, initial or data 
      self.fields['driverclass'].queryset = DriverClass.objects.filter(event=self.instance.event) 

class DriverAdmin(admin.ModelAdmin): 
    form = DriverForm 

Одно предостережение в том, что при изменении Event, опции для вашего DriverClass не не обновляются, пока вы отправьте форму. Форма будет вызывать ValidationError, и возвращаемая форма будет иметь правильный выбор. Для изменения этого поведения потребуются Ajax-запросы и динамическое обновление через Javascript.

+0

Я мог бы это сделать, это обычная практика? – Martol1ni

+0

@ Martol1ni Я предполагаю, что регулярная практика переопределяет метод '__init__' формы для таких динамических изменений для каждого экземпляра, и я думаю, что это именно то, что для атрибута' queryset' этого поля. – knbk

+0

@ Martol1ni Если вы удовлетворены этим ответом, не могли бы вы принять его и закрыть этот вопрос? – knbk

0

Games Brainiac является правильным. Это то, что вы могли бы смоделировать это как, если вы настаиваете на свойство событий на водителей:

class Event(models.Model): 
    name = models.CharField(max_length = 50) 

class DriverClass(models.Model): 
    name = models.CharField(max_length = 20) 
    event = models.ForeignKey(Event) 

class Driver(models.Model): 
    name = models.CharField(max_length = 50) 
    driverclass = models.ForeignKey(DriverClass) 

    @property 
    def event(self): 
     return self.driverclass.event 

Просто читать Django: ForeignKey limit_choices_to to equal current object's client, чтобы увидеть, что, как вы хотите на самом деле «странным образом». В том, как вы хотите, чтобы ссылочная целостность не гарантировалась.

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