I have a model with the following fields
class Entry(models.Model):
title = models.CharField(max_length=50)
comments = models.TextField()
start = models.DateField()
end = models.DateField()
remind = models.BooleanField()
and a modelform
class EntryForm(models.Model):
class Meta:
model = Entry
I want to render a form using bootstrap 3. I can render the form using the same kind of form e.g all fields horizontal or divide them by three in a row. How about more customization. Like
<label title>
<input title>
<label comments>
<input comments>
<label start> <label end>
<input start> <input end>
<label remind><input remind>
I guess this should be done manually. How can I know to which field of the form i am refering in the template. And by which field i mean is it title, is it comments? Is this correct (suppose the view has passed a form argument to the template) something like
<label for={{form.title.auto_id}}>Title</label>
{{form.title}}
is that correct? Now i can place what ever div's and arrange form fields as I like correct?Is that the right way?
How powerfull can a form of django be?
Here's a thought... Django has extensive, well-written documentation:
https://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template
Instead of guessing random things you could just read the docs.
Additionally there are a number of Django apps designed to simplify outputting form HTML in a Bootstrap style, such as:
https://github.com/dyve/django-bootstrap3 (recommended)
https://github.com/dyve/django-bootstrap-toolkit
https://github.com/tzangms/django-bootstrap-form
Related
I am looking for a way to switch and display a form in template, depending on choice in CharField in another form.
My app has the following models:
class Damage(models.Model):
damage_place = models.CharField()
damage_date = models.DateField()
class DamageType1(models.Model):
damage = models.ForeignKey(Damage)
...
class DamageType2(models.Model):
damage = models.ForeignKey(Damage)
...
class DamageType3(models.Model):
damage = models.ForeignKey(Damage)
...
Damage model has a DamageForm(forms.ModelForm) that is filled in by another user.
Each DamageType model has different fields (marked as ... for simplicity) and own DamageTypeForm1(forms.ModelForm), DamageTypeForm2(forms.ModelForm) and DamageTypeForm3(forms.ModelForm).
There is also a form in a template specifying which DamageType to choose:
class DamageSpecify(forms.Form):
DAMAGE_CHOICES = [
('DamageType1', 'DamageType1'),
('DamageType2', 'DamageType2'),
('DamageType3', 'DamageType3'),
]
damage_type = forms.CharField(choices=DAMAGE_CHOICES )
And now, after choose specific damage_type in DamageSpecify I would like to display the filled DamageForm and empty DamageType(1, 2 or 3) in template to fill and save both forms.
How could this be done?
How I'd tackle it. Write 4 forms. One, with a single ChoiceField. The other 3, to get the appropriate inputs for damage types 1 to 3 as chosen in the first. Display all the forms in your template:
<form> {% csrf_token %}
{{damage_type_form.as_p}}
<div id="type1">
{{damage_form_1.as_p}}
</div>
<div id="type2">
{{damage_form_2.as_p}}
</div>
<div id="type3">
{{damage_form_3.as_p}}
</div>
<input type="submit" ...>
</form>
(obviously, pass the four forms in your context, as you'd normally pass just one)
In your view POST processing, you will use the damage_type to determine which form is to be validated and used. Bind all four forms (to request.POST), then use the choice to decide which one gets validated and used. Ignore the other two.
(This may be the first time I've actually thought that a Function-based view will probably be easier than using the Class-Based Views)
Finally, write some JS that will hide the <div>s that are not selected in the damage_type pulldown/ ChoiceField.
This is the html django form generated for an ImageField
<div id="div_id_image" class="form-group">
<label for="id_image" class=""> Image </label>
<div class=""> <input type="file" name="image" accept="image/*" class="clearablefileinput form-control-file" id="id_image">
</div>
Now, I can write custom html code to customize this field. But, my use-case is just to add 3 classes, one for the outer div, one for the label and one for the input field itself.
Is it possible to add these 3 classes in django form without writing any custom html code
It is possible. use "django-widget-tweaks" tools. It will give you full flexibility in your form.
check out the official documentation:
https://pypi.org/project/django-widget-tweaks/
If you want to add only class name from form.py
(you can try this but code is not tested)
from django import forms
class xyzform(forms.ModelForm):
x= forms.CharField(widget= forms.TextInput
(attrs={'class':'some_class',
'id':'some_id'}))
y= forms.CharField(widget= forms.TextInput
(attrs={'class':'some_class',
'id':'some_id'}))
class Meta:
model = xyzModal
fields = [
'x',
'y'
]
I'm using Django's forms functionality to create a signup page. I've three checkboxes (BooleanField's) and I want to implement validations to ensure that the user enters at least one option.
This is the registration template
<div class="form-check form-check-inline">
{{form.is_student}}
<label class="form-check-label" for="inlineRadio1">  {{form.is_student.label}} </label>
{{form.is_teacher}}
<label class="form-check-label" for="inlineRadio2">  {{form.is_teacher.label}} </label>
{{form.is_parent}}
<label class="form-check-label" for="inlineRadio3">  {{form.is_parent.label}} </label>
</div>
This is form.py
class SignUp_Form(forms.ModelForm):
is_student = forms.BooleanField(label='Student', required=False, )
is_teacher = forms.BooleanField(label='Teacher', required=False)
is_parent = forms.BooleanField(label='Parent', required=False)
This is not the right way to do that. I would say to use one of the below methods.
Change the form fields to radio buttons. In this way you can tell the user to select one of the above and mark that field as required=True.
Or the other way is write a js function to check at least one is selected before submission.
I would personally feel to go with the first one as it makes more good way of a programmer.
THe right way to do that is to create a multiple choice required field with three choices.
I have a form which allows you to upload an image, but I want to know if it is possible to customise the markup that Django generates.
In the model it is created as an ImageField:
logo = models.ImageField(blank=True, null=True)
In the template I am creating an 'upload' form field using
{{ form.logo }}
This is the markup that gets generated:
Currently: dog.jpg
<input id="logo-clear_id" name="logo-clear" type="checkbox">
<label for="logo-clear_id">Clear</label>
<br>Change: <input id="id_logo" name="logo" type="file">
I want to know if I can change that markup by drilling down further, so that I can for example nest the checkbox to clear the image within its label. I also would like to use my own markup to separate the option to clear the form field from the option to upload a new one. However, I can't find any documentation on how to do this. I've tried outputting
{{ logo.logo-clear }}
directly but this throws an error.
The solution was to create a custom version of the widget being used in my forms.py: https://docs.djangoproject.com/en/1.10/_modules/django/forms/widgets/#ClearableFileInput
from django.forms.widgets import ClearableFileInput
class CustomImageFieldWidget(ClearableFileInput):
template_with_clear = '<label for="%(clear_checkbox_id)s">%(clear)s %(clear_checkbox_label)s</label>'
class OrganisationProfileForm(OrganisationCreateForm):
class Meta(OrganisationCreateForm.Meta):
widgets = {
'logo': CustomImageFieldWidget,
}
I'm new to Django forms and am getting hung up on something that seems like it should be very simple.
I want to create a dropdown selector that directs users to detail pages, one for each year.
In models.py I have:
class Season(models.Model):
year = models.IntegerField(unique = True, max_length=4, verbose_name = "Season (year)")
…
class season_choice(forms.Form):
choice = forms.ModelChoiceField(queryset=Season.objects.all().order_by('year'), empty_label="Season")
class Meta:
model = Season
In my template:
<form action="/season_detail/{{ choice.year }}" method="get">
{{ season_choice.as_p }}
<input type="submit" value="Go" />
</form>
The dropdown selector shows up fine, producing choices formatted like so:
<select id="id_choice" name="choice">
<option selected="selected" value="">Season</option>
<option value="1">1981</option>
<option value="2">1982</option>
<option value="3">1983</option>
…
Choosing and submitting a year, for instance 1983, now takes me to /season_detail/?choice=3 when what I what is something like /season_detail/?choice=1983
I assume I need to write that into views.py, but after reading through the Django docs and searching through the forum here and trying several approaches I'm more confused than ever.
It looks like you're mixing forms.Form and forms.ModelForm in class season_choice based on your use of forms.Form but also declaring a Meta class.
If you need a different form widget than the model default, you can over ride it in the Meta class if using a ModelForm. When using ModelForms it's best practice to explicitly list the fields to be displayed so that future fields (potentially sensitive ones) are not added by default.
class SeasonForm(forms.ModelForm):
class Meta:
model = Season
fields = ['year']
widgets = {
'year': forms.widgets.Select(),
}
Django models also have a Meta class that will allow you to provide a default ordering:
class Season(models.Model):
year = ...
class Meta:
ordering = ['-year']
If you don't want the entire Model class to have that ordering, you can either change this in your view or create a proxy model, then in your form use model = SeasonYearOrdering.
class SeasonYearOrdering(Season):
class Meta:
ordering = ['-year']
proxy = True
Another item of interest is the hard coded url in your template. You can give the urls in your urls.py names. Then in your template, you can reference these names so that if your urls.py path ever changes, your templates refer to the name and not the hard coded path.
So:
<form action="/season_detail/{{ choice.year }}" method="get">
Becomes (season_detail is the name from urls.py):
<form action="{% url "season_detail" choice.year %}" method="get">
You may change the value of option by adding to_field_name='year' to the choice ModelChoicefield in the form.
So you'll get
<option value="1981">1981</option>
<option value="1982">1982</option>
<option value="1983">1983</option>