2009-07-10 10 views
5

Ho questo modello:Il modo migliore per creare un modulo di ricerca del modello?

class Aircraft(models.Model): 
    model  = models.CharField(max_length=64, blank=True) 
    type  = models.CharField(max_length=32) 
    extra  = models.CharField(max_length=32, blank=True) 
    manufacturer = models.CharField(max_length=32) 
    engine_type = models.IntegerField("Engine Type", choices=ENGINE_TYPE, default=0) 
    cat_class = models.IntegerField("Category/Class", choices=CAT_CLASSES, default=1) 

e ho una pagina di "trovare aeromobili" in cui l'utente si presenta con una forma in cui possono inserire i dati che verranno utilizzati per trovare tutti gli aeromobili che si adatta alle loro criteri. Ad esempio, l'utente può inserire "boeing" in una casella di testo e "jet" nella casella engine_type e visualizza tutti i boeing jet nel database. Il modo in cui sto facendo questo ora è di questa forma:

class AircraftSearch(ModelForm): 
    search = forms.CharField(max_length=100, required=False) 
    class Meta: 
     model = Aircraft 
     fields = ('engine_type', 'cat_class',) 

E poi un (inutilmente complessa) vista che converte i dati da questa forma in una serie di filter() 's che vengono aggiunto al Aircraft.objects.all(). (Invece di avere 4 campi di ricerca separati per ogni CharField, li ho combinati tutti in un campo di ricerca.)

Tutto questo funziona, ma con un problema. Se l'utente desidera escludere il tipo di motore dai propri criteri di ricerca, viene bloccato perché "Qualsiasi" non è una scelta valida per il campo del tipo di motore. Dovrò creare un nuovo campo/widget per tipo di motore e categoria/classe per includere "Qualsiasi", che tipo di sconfigge lo scopo di utilizzare una vista modello in primo luogo

Sono curioso. C'è un modo migliore? Questo sembra un compito molto comune che deve essere già stato affrontato da qualcun altro, ma una ricerca su google non porta a nulla.

risposta

8

Funzionalmente, "qualsiasi" si otterrebbe semplicemente non includendo quel particolare vettore di ricerca nel filtro.

Generalmente, ModelForm s sono per la creazione e la modifica di modelli; in questo caso, non sono sicuro che sta aiutando molto di più di solo facendo una forma regolare:

class AircraftSearch(forms.Form): 
    search = forms.CharField(max_length=100, required=False) 
    engine_type = forms.ChoiceField(choices=ENGINE_TYPE) 
    cat_class = forms.ChoiceField(choices=CAT_CLASS) 

di fare la ricerca, è quindi solo filtrare quando i campi non sono vuoti:

def search(request): 
    if request.method == 'POST': 
     results = Aircraft.objects.all() 

     search = request.POST.get('search', None) 
     if search: 
      results = results.filter(Q(model=search)|Q(type=search)|Q(extra=search)|Q(manufacturer=search)) 

     engine_type = request.POST.get('engine_type', None) 
     if engine_type: 
      results = results.filter(engine_type=engine_type) 

     cat_class = request.POST.get('cat_class', None) 
     if cat_class: 
      results = results.filter(cat_class=cat_class) 

     return render_to_response('aircraft.html', {'form': AircraftSearch(request.POST), 'aircraft': results}) 

    return render_to_response('aircraft.html', {'form': AircraftSearch()}) 
+1

Il problema è che "scelte = ENGINE_TYPE" include solo scelte valide come "jet" e "pistone", ecc. E non "Qualsiasi". È necessario aggiungere questa opzione all'elenco ENGINE_TYPE oppure ogni SearchForm includerà una delle opzioni e sarai costretto a filtrare in base a uno specifico tipo di motore. Non è un problema per me creare un searchform con l'opzione "Any" aggiunta all'elenco ENGINE_TYPE, ma mi sembra un hacker e se esiste un metodo migliore "non-hacky" preferirei farlo. – priestc

+1

Mi sembra che fare qualcosa come options = (('', 'Any'),) + ENGINE_TYPE sia una soluzione abbastanza pulita per questo. Non si introduce "alcun" nel modello, ma è disponibile per il modulo. – tghw

3

Penso che non dovresti usare un ModelForm.
L'usescase del ModelForm tipico è la manipolazione dei dati e non la sua ricerca.

Invece, crea un modulo completamente nuovo, basato sui campi che ti servono e con le caselle di controllo che l'utente (de-) seleziona per disabilitare la ricerca di un particolare campo.
Ovviamente, è comunque necessario utilizzare le scelte definite nel modello, semplicemente importando il file e utilizzando tale elenco.

Problemi correlati