Джанго - Как сделать форму для внешних ключей модели? - PullRequest
8 голосов
/ 19 апреля 2011

Вот что я пытаюсь сделать. Мне интересно, если кто-то может предложить хороший подход:

models.py:

class Color(models.Model):
    name = models.CharField(...

class Speed(models.Model):
    name = models.CharField(...

class Dog(models.Model):
    name = models.CharField(...
    color = models.ForeignKey(Color...
    speed = models.ForeignKey(Speed...

class DogRequest(models.Model):
    dog = models.ForeignKey(Dog...
    request_time = models.DateTimeField()

Теперь я хочу иметь страницу, где пользователь может ввести или отредактировать DogRequest, но форма должна выглядеть следующим образом:

Enter Dog Request:
---------------------
color (dropdown V)
speed (dropdown V)
|save|

Так как бы я спроектировал эту форму в виде? Проблема в том, что пользователь будет вводить свойства собаки, а не собаки. Поэтому мне нужно найти или создать запись о собаке в зависимости от того, что вводит пользователь.

Пока я пробовал что-то вроде этого:

class DogRequestForm(ModelForm):
    class Meta:
        model = DogRequest
        fields = ('request_time','color','speed')
    color = forms.ModelChoiceField(queryset=Color.objects.all())
    speed = forms.ModelChoiceField(queryset=Speed.objects.all())

Теперь, если предположить, что это даже работает, куда мне поместить код, чтобы выяснить, какую запись Dog использовать (или создать) в зависимости от того, что введено для цвета и скорости? И как мне заполнить форму из DogRequest?

1 Ответ

9 голосов
/ 19 апреля 2011

Я не думаю, что вы хотите использовать ModelForm здесь. Он никогда не будет действителен без какого-либо хакерства, так как вы не найдете и не создадите объект dog до вызова is_valid().

Вместо этого я бы просто использовал обычную форму, а затем переопределил метод сохранения DogRequest, чтобы найти или создать собаку.

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

class DogRequestForm(forms.Form):
    id = forms.IntegerField(required=False, widget=forms.HiddenInput())
    color = forms.ModelChoiceField(queryset=Color.objects.all())
    speed = forms.ModelChoiceField(queryset=Speed.objects.all())

и затем, когда вы создаете экземпляр этой формы для представления редактирования, вам нужно создать его экземпляр примерно так:

data = {
    'id': dog_request_id,
    'color': dog_color,
    'speed': dog_speed,
}
form = DogRequestForm(data)

где вы заполняете текущие dog_request_id, dog_color и dog_speed из существующего объекта DogRequest.

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