2010-08-29 5 views
3

Je souhaite créer un formulaire permettant de filtrer les recherches sans aucun champ. Par exemple donné ce code:Django Formulaire sans champs obligatoires

models.py:

class Message(models.Model): 
    happened = models.DateTimeField() 
    filename = models.CharField(max_length=512, blank=True, null=True) 
    message = models.TextField(blank=True, null=True) 
    dest = models.CharField(max_length=512, blank=True, null=True) 
    fromhost = models.ForeignKey(Hosts, related_name='to hosts', blank=True, null=True) 
    TYPE_CHOICES = ((u'Info', u'Info'), (u'Error', u'Error'), (u'File', u'File'), (u'BPS', u'BPS'),) 
    type = models.CharField(max_length=7, choices=TYPE_CHOICES) 
    job = models.ForeignKey(Jobs) 

views.py:

WHEN_CHOICES = ((u'', ''), (1, u'Today'), (2, u'Two days'), (3, u'Three Days'), (7, u'Week'),(31, u'Month'),) 

class MessageSearch(ModelForm): #Class that makes a form from a model that can be customized by placing info above the class Meta 
     message = forms.CharField(max_length=25, required=False) 
     job = forms.CharField(max_length=25, required=False) 
     happened = forms.CharField(max_length=14, widget=forms.Select(choices=WHEN_CHOICES), required=False) 
     class Meta: 
      model = Message 

C'est le code que j'ai maintenant. Comme vous pouvez le voir, il fait une forme basée sur un modèle. J'ai redéfini le message dans le formulaire parce que j'utilise un filtre icontains donc je n'ai pas besoin d'une boîte de texte géante. J'ai redéfini la date surtout parce que je ne voulais pas avoir à tripoter des dates (je déteste travailler avec des dates! Qui ne le fait pas?) Et j'ai changé le champ d'emplois parce que sinon je recevais une liste déroulante d'emplois existants voulait être en mesure de rechercher par des mots communs. J'ai donc pu marquer tous ceux qui ne l'étaient pas

Le problème est de marquer tous mes autres champs comme requis car dans le modèle ils ne sont pas autorisés à être vides.

Maintenant, dans le modèle, ils ne peuvent pas être vides. Si elles sont vides, les données sont mauvaises et je ne le veux pas dans la base de données. Toutefois, le formulaire est uniquement un formulaire de filtre sur une page pour afficher les données. Je ne vais jamais enregistrer à partir de ce formulaire, donc je me fiche que les champs soient vides ou non. Donc, y a-t-il un moyen facile de rendre tous les champs comme requis = false tout en utilisant la classe Meta: model = Message dans le formulaire? C'est vraiment pratique que je peux faire un formulaire directement à partir d'un modèle.

Aussi ceci est ma première tentative sérieuse d'une application django donc si quelque chose est mal absurdement s'il vous plaît être gentil :)

+0

Ok donc dans ce cas précis, il était assez facile à réparer. Je n'avais vraiment qu'un champ obligatoire, le champ de type, donc j'ai formaté celui-ci à la main mais en général j'aimerais toujours connaître la réponse à cette question. Merci! – Eric

Répondre

5

Vous pouvez créer un ModelForm personnalisé qui répondent à vos besoins. Ce ModelForm personnalisé remplacera la méthode de sauvegarde et définir tous les champs pour être non-requis:

from django.forms import ModelForm 

class SearchForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(SearchForm, self).__init__(*args, **kwargs) 
     for key, field in self.fields.iteritems(): 
      self.fields[key].required = False 

Vous pouvez déclarer vos formulaires en appelant simplement au lieu du ModelForm, par exemple:

class MessageForm(SearchForm): 
    class Meta: 
     model = Message 
+0

Eh bien, je sais que je peux le faire mais je ne veux pas faire ça. Si je définis chaque champ, je ne peux pas utiliser le modèle pour définir ma forme, ce qui est une très bonne fonctionnalité. Je veux savoir s'il existe un moyen de faire cela globalement pour ce formulaire spécifique sans abandonner la fonctionnalité de classe Meta: model = Message que j'aime bien. – Eric

+0

Mais c'est exactement ce que fait le ModelForm personnalisé. Vous ne définissez le SearchForm qu'une seule fois et vous pouvez l'utiliser pour déclarer votre MessageForm - y compris également l'option Meta model. –

+0

Intéressant ... Je suppose que je ne l'ai pas lu assez attentivement la première fois. C'est très intéressant. Merci! – Eric

1

Vous pouvez également passer empty_permitted=True lorsque vous instancier la forme, par exemple,

form = MessageSearch(empty_permitted=True) 

cette façon, vous pouvez toujours avoir des règles de validation normales pour quand quelqu'un n'entrer des données dans le formulaire.

0

que je donnerais un essai au module django-filtre:

http://django-filter.readthedocs.io/en/develop/

champs ne sont pas nécessaires. ce sont des filtres en fait. Il ressemblerait à ceci:

import django_filters 

class MessageSearch(django_filters.FilterSet): 

    class Meta: 
     model = Message 
     fields = ['happened', 'filename', 'message', '...', ] 

    # django-filter has its own default widgets corresponding to the field 
    # type of the model, but you can tweak and subclass in a django way : 
    happened = django_filters.DateFromToRangeFilter() 

filtres obligatoires, cachés peuvent être définis si vous souhaitez affiner une liste de modèle en fonction de quelque chose comme les droits des utilisateurs, etc.

aussi: installer un filtre sur un « inverse «relation (le foreignkey n'est pas dans le modèle filtré: le modèle est référencé ailleurs dans une autre table), est facile, juste le nom de la table où la clé étrangère du champ de modèle filtré est:

# the 'tags' model has a fk like message = models.ForeignKey(Message...) 
    tags= django_filters.<some filter>(name='tags') 

rapide extensible et propre à l'installation. s'il vous plaît noter que je n'ai pas écrit ce module, je suis juste très heureux avec elle :)

Questions connexes