2010-06-09 3 views
10

Sto cercando di utilizzare ModelForm per aggiungere i miei dati. Funziona bene, ad eccezione del fatto che l'elenco a discesa ForeignKey mostra tutti i valori e voglio solo che mostri i valori pertinenti per l'utente che ha effettuato l'accesso.Come faccio a filtrare i valori in un modulo Django usando ModelForm?

Ecco il mio modello per ExcludedDate, il record voglio aggiungere:

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 

Ecco il modello per la categoria, che è la tabella contenente il rapporto che vorrei limitare dall'utente:

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

    def __unicode__(self): 
     return self.name 

E, infine, il codice del modulo:

class ExcludedDateForm(ModelForm): 

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

Come faccio ad avere il modulo per visualizzare su il sottoinsieme di categorie in cui category.user è uguale all'utente loggato?

risposta

20

È possibile personalizzare il modulo in 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) 

E in vista, quando si costruisce il modulo, oltre alle params forma standard, è necessario specificare anche l'utente corrente:

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

Questo ha funzionato "facile come torta!" Apprezzo non solo la tua risposta, ma la completezza della tua risposta. – malandro95

+0

Felice di essere di aiuto :) –

+0

Quindi ... mentre il modulo ora sembra fantastico, il cambiamento ha rotto la vista che aggiunge i dati. Qualche idea? (Codice qui sotto) – malandro95

0

Qui esempio:

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 può provare qualcosa di simile:

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

Probabilmente funzionerà, ma è una cattiva pratica. Non dovresti hackerare il modulo al di fuori della classe del modulo. È molto più semplice definire questa logica in __init__ –

+0

Sì ... Sono d'accordo .. Aggiorna già il mio post. – Saff

0

So che questo è vecchio; ma è uno dei primi risultati di ricerca di Google, quindi ho pensato di aggiungere come ho trovato a farlo.

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'] 

Dove 'model_to_filter' è una ForiegnKey del modello "CustomModel"

Perché mi piace questo metodo: nel "CustomModelFilter" si può anche cambiare il modo di default che l'oggetto del modello viene visualizzato in il ChoiceField che viene creato, come ho fatto sopra.