tags:

views:

17

answers:

1

Hi, I want to make a form used to filter searches without any field being required. For example given this code:

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

That's the code I have now. As you can see it makes a form based on a model. I redefined message in the form because I'm using an icontains filter so I didn't need a giant text box. I redefined the date mostly because I didn't want to have to mess around with dates (I hate working with dates! Who doesnt?) And I changed the jobs field because otherwise I was getting a drop down list of existing jobs and I really wanted to be able to search by common words. So I was able to mark all of those as not required

The problem is it's marking all my other fields as required because in the model they're not allowed to be blank.

Now in the model they can't be blank. If they're blank then the data is bad and I don't want it in the DB. However the form is only a filter form on a page to display the data. I'm never going to save from that form so I don't care if fields are blank or not. So is there an easy way to make all fields as required=false while still using the class Meta: model = Message format in the form? It's really handy that I can make a form directly from a model.

Also this is my first serious attempt at a django app so if something is absurdly wrong please be kind :)

A: 

You can create a custom ModelForm that suit your needs. This custom ModelForm will override the save method and set all fields to be non-required:

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

So you could declare your forms by simply calling instead of the ModelForm, e.g.:

class MessageForm(SearchForm):
    class Meta:
        model = Message
Cesar Canassa
Well I know I can do that but I don't want to do that. If I define every field then I can't use the model to define my form which is a really good feature.I want to know if there's a way to do that globally for that specific form without giving up the class Meta:model = Message functionality that I like.
Eric
But that's exactly what the custom ModelForm does. You define the SearchForm only once and then you can use it declare your MessageForm - also including the Meta model option.
Cesar Canassa
Interesting..I guess I didn't read it closely enough the first time. That's pretty interesting. Thanks!
Eric