2011-02-24 18 views
11

Necesito hacer un formulario, que tiene 1 selección y 1 entrada de texto. Seleccione debe tomarse de la base de datos. modelo se parece a esto:opciones de campo() como queryset?

class Province(models.Model): 
    name = models.CharField(max_length=30) 
    slug = models.SlugField(max_length=30) 

    def __unicode__(self): 
     return self.name 

filas de TI para este sólo se añaden por admin, pero todos los usuarios pueden ver en las formas. Quiero hacer un ModelForm a partir de eso. Hice algo como esto:

class ProvinceForm(ModelForm): 
    class Meta: 
     CHOICES = Province.objects.all() 

     model = Province 
     fields = ('name',) 
     widgets = { 
      'name': Select(choices=CHOICES), 
     } 

pero no funciona. La etiqueta de selección no se muestra en html. ¿Qué hice mal?

ACTUALIZACIÓN:

Esta solución funciona como Wanto a trabajar:

class ProvinceForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(ProvinceForm, self).__init__(*args, **kwargs) 
     user_provinces = UserProvince.objects.select_related().filter(user__exact=self.instance.id).values_list('province') 
     self.fields['name'].queryset = Province.objects.exclude(id__in=user_provinces).only('id', 'name') 

    name = forms.ModelChoiceField(queryset=None, empty_label=None) 

    class Meta: 
     model = Province 
     fields = ('name',) 

Respuesta

6

ModelForm cubre todas sus necesidades (también comprobar el Conversion List) Modelo

:

class UserProvince(models.Model): 
    user = models.ForeignKey(User) 
    province = models.ForeignKey(Province) 

Forma:

class ProvinceForm(ModelForm): 
    class Meta: 
     model = UserProvince 
     fields = ('province',) 

Vista: respuesta

if request.POST: 
     form = ProvinceForm(request.POST) 
     if form.is_valid(): 
      obj = form.save(commit=True) 
      obj.user = request.user 
      obj.save() 
    else: 
     form = ProvinceForm() 
+0

He actualizado mi post con la solución de trabajo. – robos85

+6

+1: pero no debería 'commit = False', de lo contrario golpeará el db dos veces –

11

Leer de Maersu para el método que se acaba "funciona".

Si desea personalizar, saber que las decisiones toma una lista de tuplas, es decir (('val','display_val'), (...), ...)

opciones doc:

Un iterable (por ejemplo, una lista o tupla) de 2-tuplas a utilizar como opciones para este campo .

from django.forms.widgets import Select 


class ProvinceForm(ModelForm): 
    class Meta: 
     CHOICES = Province.objects.all() 

     model = Province 
     fields = ('name',) 
     widgets = { 
      'name': Select(choices=((x.id, x.name) for x in CHOICES)), 
     } 
+0

Hola @yuij, no estoy usando ModelForm pero tengo un requisito similar donde necesito tener opciones de queryset en charfield en Model sí mismo. Probé la manera sugerida, pero en mi caso me da un error como "django.core.exceptions.AppRegistryNotReady: los modelos aún no están cargados", donde dice que el modelo aún no está cargado. Entonces, ¿alguna idea de cómo podemos lograrlo Modelos? – CrazyGeek

+0

@CrazyGeek de cualquier forma, donde sea que esté inyectando esto, si se llama en el momento de inicio de la clase de modelo (es decir, antes de la aplicación lista) va a ser un valor estático ... no tomará forma hasta el reinicio. Debe asegurarse de que esté en un ModelForm o código * view * relevante que se ejecuta por solicitud. –

+0

No estoy usando ModelForm porque estoy usando django for rest api solamente. – CrazyGeek

Cuestiones relacionadas