2010-06-09 44 views
10

Estoy tratando de usar ModelForm para agregar mis datos. Está funcionando bien, excepto que la lista desplegable ForeignKey muestra todos los valores y solo quiero que muestre los valores que son pertinentes para el usuario que ha iniciado sesión.¿Cómo puedo filtrar valores en un formulario de Django usando ModelForm?

Aquí es mi modelo para ExcludedDate, el registro quiero añadir:

class ExcludedDate(models.Model): 
    date = models.DateTimeField() 
    reason = models.CharField(max_length=50) 
    user = models.ForeignKey(User) 
    category = models.ForeignKey(Category) 
    recurring = models.ForeignKey(RecurringExclusion) 

    def __unicode__(self): 
     return self.reason 

Aquí es el modelo para la categoría, que es la tabla que contiene la relación que me gustaría limitar por el usuario:

class Category(models.Model): 
    name = models.CharField(max_length=50) 
    user = models.ForeignKey(User, unique=False) 

    def __unicode__(self): 
     return self.name 

Y, por último, el código del formulario:

class ExcludedDateForm(ModelForm): 

    class Meta: 
     model = models.ExcludedDate 
     exclude = ('user', 'recurring',) 

¿Cómo consigo el formulario para mostrar en ¿El subconjunto de categorías donde category.user es igual al usuario que inició sesión?

Respuesta

20

Puede personalizar la forma en la init

class ExcludedDateForm(ModelForm): 
    class Meta: 
     model = models.ExcludedDate 
     exclude = ('user', 'recurring',) 
    def __init__(self, user=None, **kwargs): 
     super(ExcludedDateForm, self).__init__(**kwargs) 
     if user: 
      self.fields['category'].queryset = models.Category.objects.filter(user=user) 

Y en vistas, en la construcción de su formulario, además de los parametros de forma estándar, deberá especificar también el usuario actual:

form = ExcludedDateForm(user=request.user) 
+0

Esto funcionó "¡fácil como un pastel!" Agradezco no solo su respuesta, sino la integridad de su respuesta. – malandro95

+0

Me alegro de ser de ayuda :) –

+0

Entonces .... mientras que el formulario ahora se ve muy bien, el cambio rompió la vista que agrega los datos. ¿Algunas ideas? (Código de abajo) – malandro95

0

Aquí ejemplo:

models.py

class someData(models.Model): 
    name = models.CharField(max_length=100,verbose_name="some value") 

class testKey(models.Model): 
    name = models.CharField(max_length=100,verbose_name="some value") 
    tst = models.ForeignKey(someData) 

class testForm(forms.ModelForm): 
    class Meta: 
     model = testKey 

views.py

... 
.... 
.... 
    mform = testForm() 
    mform.fields["tst"] = models.forms.ModelMultipleChoiceField(queryset=someData.objects.filter(name__icontains="1")) 
... 
... 

O u puede intentar algo como esto:

class testForm(forms.ModelForm): 
    class Meta: 
     model = testKey 

def __init__(self,*args,**kwargs): 
    super (testForm,self).__init__(*args,**kwargs) 
    self.fields['tst'].queryset = someData.objects.filter(name__icontains="1") 
+1

Eso probablemente funcione, pero es una mala práctica. No debe hackear el formulario fuera de la clase de formulario. Es mucho más simple definir esta lógica en __init__ –

+0

Sí ... Acepto ... ya actualizo mi publicación. – Saff

0

Sé que esto es viejo; pero es uno de los primeros resultados de búsqueda de Google, así que pensé en agregar cómo lo encontré.

class CustomModelFilter(forms.ModelChoiceField): 
    def label_from_instance(self, obj): 
     return "%s %s" % (obj.column1, obj.column2) 

class CustomForm(ModelForm): 
    model_to_filter = CustomModelFilter(queryset=CustomModel.objects.filter(active=1)) 

    class Meta: 
     model = CustomModel 
     fields = ['model_to_filter', 'field1', 'field2'] 

Dónde model_to_filter 'es un ForiegnKey del modelo "CustomModel"

Por qué me gusta este método: en el "CustomModelFilter" También se puede cambiar la forma predeterminada en que el objeto del modelo se muestra en el ChoiceField que se crea, como he hecho anteriormente.

Cuestiones relacionadas