Question

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))
Was it helpful?

Solution

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.

OTHER TIPS

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

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.

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',)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top