Как использовать selectionField, объявленный в модели, в форме. Джанго

У меня есть это в моем model.py

class marca(models.Model):
    marcas = (
        ('chevrolet', 'Chevrolet'),
        ('mazda', 'Mazda'),
        ('nissan', 'Nissan'),
        ('toyota', 'Toyota'),
        ('mitsubishi', 'Mitsubishi'),
    )

    marca = models.CharField(max_length=2, choices= marcas)
    def __unicode__(self):
        return self.marca

И мне нужно использовать это в моем form.py Я пробовал это, но это не работает.

class addVehiculoForm(forms.Form):
    placa                   = forms.CharField(widget = forms.TextInput())
    tipo                    = forms.CharField(max_length=2, widget=forms.Select(choices= tipos_vehiculo))
    marca                   = forms.CharField(max_length=2, widget=forms.Select(choices= marcas))

person Hugo Montoya    schedule 04.04.2013    source источник


Ответы (4)


Переместите свои варианты, чтобы они были над моделью, в корне вашего models.py:

marcas = (
        ('chevrolet', 'Chevrolet'),
        ('mazda', 'Mazda'),
        ('nissan', 'Nissan'),
        ('toyota', 'Toyota'),
        ('mitsubishi', 'Mitsubishi'),)

class Marca(models.Model):

    marca = models.CharField(max_length=25,choices=marcas)

Затем в вашем файле, где вы объявляете форму:

from yourapp.models import marcas

class VehiculoForm(forms.Form):

     marca = forms.ChoiceField(choices=marcas)

Я также исправил некоторые другие проблемы для вас:

  • Имена классов должны начинаться с заглавной буквы
  • Вам нужно увеличить max_length вашего символьного поля, потому что вы сохраняете слово chevrolet каждый раз, когда кто-то выбирает Chevrolet в раскрывающемся списке выбора.

Если вы просто создаете форму для сохранения записей для модели Marca, используйте ModelForm, например:

from yourapp.models import Marca

class VehiculoForm(forms.ModelForm):
     class Meta:
         model = Marca

Теперь django автоматически отобразит поле выбора.

person Burhan Khalid    schedule 04.04.2013
comment
в формах.CharField нет выбора. super(CharField, self).__init__(*args, **kwargs) TypeError: __init__() got an unexpected keyword argument 'choices' - person Julio Marins; 12.01.2018
comment
Опечатка, должно быть forms.ChoiceField - person Burhan Khalid; 12.01.2018

Вам нужно определить кортеж выбора marcas вне класса модели class marca.

Затем вы можете сделать следующее в forms.py, чтобы использовать

from models import marcas

class addVehiculoForm(forms.Form):
    marca  = forms.CharField(max_length=2, widget=forms.Select(choices= marcas))
    ...
person Rohan    schedule 04.04.2013

Я предпочитаю держать выбор внутри модели, чтобы он не смешивался с другими моделями. Тогда решение будет таким:

модели.ру:

Same as in question.

формы.py:

from yourapp.models import marca

class VehiculoForm(forms.Form):
     marca = forms.ChoiceField(choices=marca.marcas)

     class Meta:
         model = marca
         fields= ('marca')

Вы также можете просто определить мета, если вам нужны поля модели по умолчанию.

person Varje    schedule 03.08.2018

Существует также другой способ сделать это, если выбор (кортеж) инициализируется как частный атрибут, например

модели.py

class Marca(models.Model):
    __marcas = (                          #private attributes
          ('chevrolet', 'Chevrolet'),
          ('mazda', 'Mazda'),
          ('nissan', 'Nissan'),
          ('toyota', 'Toyota'),
          ('mitsubishi', 'Mitsubishi'),
    )

    marca = models.CharField(max_length=100, choices= __marcas)
    def __unicode__(self):
        return self.marca

формы.py

from yourapp.models import Marca        #import model instead of constant

class VehiculoForm(forms.Form):
    marca = forms.ChoiceField(choices= Marca._meta.get_field('marca').choices)

    #If you want to get the default model field
    #or just straight get the base field (not prefer solution)
    marca = Marca._meta.get_field('marca')

    #or define in class Meta (prefer and better solution)
    class Meta:
        model = Marca
        fields = ('marca',)
person Kyle_397    schedule 19.05.2020