Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make django crispy form to hide a particular field?

I'm trying to make my date_modified field as hidden since I have passed datetime.now parameter on defining date_modified field in model.

model.py

class Guide(models.Model):
    name = models.CharField(max_length=50)
    sno = models.CharField(max_length=50)
    date_created = models.DateTimeField(default=datetime.now, blank=True)
    date_modified = models.DateTimeField(default=datetime.now, blank=True)

    def __unicode__(self):
        return unicode(self.name)

views.py

class GuideFormUpdateView(UpdateView):
    model = Guide
    fields = ['name', 'sno', 'date_modified']
    template_name_suffix = '_update_form'
    success_url = reverse_lazy('Guides')

corresponding form forms.py looks like

<form role="form" method="POST" action="{% url 'Guideform-edit' object.pk %}"
              class="post-form form-horizontal" enctype="multipart/form-data">{% csrf_token %}
{{ form|crispy }}
<button type="submit" value="Upload" class="save btn btn-default btn-primary center-block">Update</button>

        </form>

This form displays date_modified field. But I don't want this field on frontend instead I want the value of this field in model or db_table should get updated. I know how to hide this particular field in jquery but I don't want to touch those js tools. Is there any way to make crispy to exclude that particular field like {{ form|crispy|exclude:date_modified }} ..

like image 762
Avinash Raj Avatar asked Feb 08 '16 12:02

Avinash Raj


3 Answers

Instead of using Generic Form that your UpdateView will use implicitly, create your custom Form. And in your custom Form change the widget of the date_modified field.

In your forms.py

from django.forms import ModelForm, HiddenInput
class GuideForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(GuideForm, self).__init__(*args, **kwargs)
        self.fields['date_modified'].widget = HiddenInput()

    class Meta:
        fields = ('name', 'sno', 'date_modified', )
        model = models.Guide

In your views.py

class GuideFormUpdateView(UpdateView):
    model = Guide
    form_class = forms.GuideForm
    template_name_suffix = '_update_form'
    success_url = reverse_lazy('Guides')

To automatically update date_modified whenever you update the record, you need to use attributes auto_now and auto_now_add instead of default. See Docs. So your model will be

class Guide(models.Model):
    name = models.CharField(max_length=50)
    sno = models.CharField(max_length=50)
    date_created = models.DateTimeField(auto_now_add=True, blank=True)
    date_modified = models.DateTimeField(auto_now=True, blank=True)

    def __unicode__(self):
        return unicode(self.name)
like image 61
Muhammad Tahir Avatar answered Sep 28 '22 09:09

Muhammad Tahir


You can hide a field in a form class like so:

Field('field_name', type="hidden")

Where Field is from crispy_forms.layout

Don't forget that if he field cannot be left empty, you'll still need to pass an appropriate value before saving it.

Abstract example:

class GuideFormHiddenField(GuideFormUpdateView):
    def __init__(self, *args, *kwargs):

        Field('date_modified', type="hidden")

This is the easiest way. You can of course make an entirely new form, or implement your fields individual, and use a condition to determine the visibility of a certain field; which would be something like if User.is_authenticated(): ... .

like image 33
Pouria Avatar answered Sep 28 '22 08:09

Pouria


I think this should work:

from django.forms.models import modelform_factory

class GuideFormUpdateView(UpdateView):
    model = Guide
    form_class = modelform_factory(Guide, widgets={"date_modified": HiddenInput })
    fields = ['name', 'sno', 'date_modified']
    template_name_suffix = '_update_form'
    success_url = reverse_lazy('Guides')

See here modelform_factory.

like image 40
doru Avatar answered Sep 28 '22 08:09

doru