2013-03-12 5 views
1

J'ai un petit problème avec les formulaires Django. Fondamentalement, j'ai 2 formes, l'une est une recherche à terme libre, les autres sont des filtres. Le champ du terme ne devrait être requis que si aucun filtre n'est sélectionné par l'utilisateur. J'ai quelque chose comme ça (mais avec plus de filtres dans la même classe):Django: Modifier dynamiquement l'exigence de forme, selon une autre forme

class Term(forms.Form): 
      terms = forms.CharField(
      label='Term', 
      required=True, # but false if the filters is selected 
      error_messages={'required': 'Please enter at least one search term'}, 
      widget=TextInput(attrs={ 
      'class':'textEntry', 
      'placeholder': 'Enter search'})) 

    class Filter(forms.Form): 
      filter = forms.ModelChoiceField(
      choices = [1,2, 3], 
      label = "Filter", 
      required = False) 

J'ai cherché partout mais j'ai trouvé aucun résultat. Avez-vous une idée? Je vous remercie.

Répondre

1

Vous devez transmettre filter à votre formulaire de terme lorsque vous l'instanciez, puis définir la valeur requise pour terms de manière appropriée. J'ai légèrement modifié les noms pour mieux les distinguer de vos classes de formulaire.

# forms.py 
class TermForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     filter = kwargs.pop('filter', None) 
     super(self, TermForm).__init__(*args, **kwargs) 
     if filter: 
      self.fields['terms'].error_messages = { 
       'required': 'Please enter at least one search term' 
      } 
     else: 
      self.fields['terms'].required = False 

    terms = forms.CharField(
     label='Term', 
     widget=TextInput(attrs={ 
      'class': 'textEntry', 
      'placeholder': 'Enter search'})) 

# views.py, assuming Django 1.4.x+ 
from django.shortcuts import render 
from your_app.forms import TermForm, FilterForm 

def a_view(request): 
    filter_form = FilterForm(request.POST or None) 

    if request.method == 'POST' and filter_form.is_valid(): 
     term_form = TermForm(request.POST or None, 
      filter_form.cleaned_data.get('filter') 
     if term_form.is_valid(): 
      # do something 

    return render(request, 'a-template.html', 
     {'filter_form': filter_form, 'term_form': term_form}) 

Tous les champs sont automatiquement requis, sauf si vous les définissez expressément de ne pas être, ce qui explique pourquoi la logique de la dérogation __init__ peut sembler en arrière. Si vous devez indiquer visuellement que le champ est requis lorsqu'un filter est choisi, vous devrez ajouter du JavaScript pour le faire.

+0

Une rétrogradation? Vraiment? Si vous avez une meilleure solution, postez-la. – Brandon