How to use a choiceField declared in the model, in a form. django
Asked Answered
S

4

8

I have this in my 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

And I need to use it in my form.py I tried this but it doesn't work.

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))
Stravinsky answered 4/4, 2013 at 3:59 Comment(0)
H
10

Move your choices to be above the model, in the root of your 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)

Then in your file where you declare the form:

from yourapp.models import marcas

class VehiculoForm(forms.Form):

     marca = forms.ChoiceField(choices=marcas)

I also fixed some other problems for you:

  • Class names should start with a capital letter
  • You need to increase the max_length of your character field because you are storing the word chevrolet anytime someone will select Chevrolet in the choice drop down.

If you are just creating a form to save records for Marca model, use a ModelForm, like this:

from yourapp.models import Marca

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

Now, django will render the choice field automatically.

Hyperpituitarism answered 4/4, 2013 at 4:8 Comment(2)
there is no choices on forms.CharField. super(CharField, self).__init__(*args, **kwargs) TypeError: __init__() got an unexpected keyword argument 'choices' Isoprene
Typo, it should be forms.ChoiceFieldHyperpituitarism
R
4

You need to define the choices tuple marcas outside of model class class marca.

Then you can do following in forms.py to use

from models import marcas

class addVehiculoForm(forms.Form):
    marca  = forms.CharField(max_length=2, widget=forms.Select(choices= marcas))
    ...
Rialto answered 4/4, 2013 at 4:3 Comment(0)
N
1

There is also another way of doing this if the choices (tuple) is initialized as private attribute like so

models.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

forms.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',)
Nut answered 19/5, 2020 at 7:34 Comment(0)
R
0

I prefer holding choices still inside the model, so they do not get mixed with other models. Then the solution would be:

models.py:

Same as in question.

forms.py:

from yourapp.models import marca

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

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

You could also just define meta, if you want default model fields.

Retiform answered 3/8, 2018 at 12:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.