I am setting up django registration, and I came across this piece of code in the RegistrationForm --
attrs_dict = { 'class': 'required' }
email = forms.EmailField(widget=forms.TextInput
(attrs=dict(attrs_dict, maxlength=75)),
label='Email')
What does the part (attrs=dict(attrs_dict, maxlength=75)) mean/do? I know what the maxlength part does but was unclear what the creation of a dictionary is doing, and what the attrs_dict is doing. Any explanation of this piece of code would be great. Thank you.
A bit of test showed that dict(attr_dict, maxlenght=75) equals to
{'class': 'required', 'maxlength':75}
So when the email filed is rendered to an html element, 2 attributes, class and maxlength will be added to the label.
It is creating a dictionary of attributes which will be required to add validation kind of things in finally rendered form, in this way we dont need to do anything in the template code to add validation and security.
Each form field in django uses a widget. You can either specify it during field creation or a default widget is used.
Here you are specifying widget TextInput on EmailField
(attrs=dict(attrs_dict, maxlength=75)) becomes:
{'class': 'required', 'maxlength':75}
Now these will be present as attributes in the rendered html for this widget. So, rendered html for field email would look like:
<input id="id_email" type="text" class="required" maxlength="75" name="email" />
Related
I have select field in my html
<select class="form-select" name="is_recurrent" id="payment">
<option value="False" class="option" selected>One-time fee</option>
<option value="True" class="option">Subscription</option>
</select>
I have model Donate in models.py
class Donate(BaseModel):
is_recurrent = models.BooleanField(default=False)
...
I have form in forms.py
class DonateForm(forms.Form):
is_recurrent = fields.BooleanField(???)
...
How can I pass True into form if subscription is selected and false if one-time fee is selected
When you instantiate your form in the view, you pass in the POST data:
form = DonateForm(data=request.POST)
That will auto-populate the form with the information that the user selected in the form prior to form submission.
If you're using Django-forms, it's really easy to do so, you don't even need to build the form! From your HTML code I can see you are trying to do so, creating an HTML form, I recommend you going through Django-forms information page (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms) since you don't really need to create all of the input boxes, the Django Forms takes care of that for you, you just need to pass the variables you want to edit using the form.
I have a form that splits the date and time from a datetime field in the model.
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('name', 'description', 'start', 'end',)
widgets = {
'start': forms.SplitDateTimeWidget(),
'end': forms.SplitDateTimeWidget(),
}
How can I add a datepicker and timepicker to each separate input box that is rendered?
Setting:
'start': forms.SplitDateTimeWidget(attrs={'type': 'date'})
makes both inputs datepicker but I need the second one to be a timepicker..
I am using Django 2.0, bootstrap and crispy forms
forms.SplitDateTimeWidget() renders an Html input that may contain some attributes that you will need in your template:
forms.SplitDateTimeWidget(attrs={'attrs': 'attrs'})`.
# You don't need to edit the "input:type", type text is good
The rendering will be something like that
<input type='text' name='field_name_0' id='id_field_name_0' attrs='attrs'>
<input type='text' name='field_name_1' id='id_field_name_1' attrs='attrs'>
According to the documentation, New in Django 2.*
You can add seperate attributes.
# Free to add attributes that you want
'start': forms.SplitDateTimeWidget(
date_attrs({'class':'datepicker'}), # or override the ID, "id":id
time_attrs({'class':'timepicker'}),
)
Since I do not know what kind of Datetime neither Timepicker that you use in your project. So, in your js call each of them by their conventional name class...
$(".datepicker").datepicker();
$(".timepicker").timepicker();
I would like to achieve the same effect as google login page that the Label of the text field is shown in the field itself. When any characters is typed in the filed, the label automatically disappeared.
I know how to achieve similar effect with html + java script, like:
<input type="text" name="" id="" value="Email" class="gray" onclick="if(this.value=='Email')
{this.value='';this.className='black'}" onblur="if(this.value=='')
{this.value='Email';this.className='gray'}" />
But could django form does the same effect? I know I can specify initial in the CharField, but it won't disappear on typing.
forms.CharField(max_length=100, label=_("Email"), initial='xxx')
There is a html5 prop called placeholdertext. Here is a Blogpost about how to use it with django forms. Django HTML5 input placeholders
Excerpt:
class MyForm(Form):
name = forms.CharField(widget=forms.TextInput({ "placeholder": "Joe Recruiter" }))
I have the following form:
class ReviewForm(forms.ModelForm):
class Meta:
model = Review
widgets = {
'tipo' : forms.RadioSelect(),
}
But I want to use images as the values of my radio buttons, the image will vary according to the option, like this:
<input type="radio" id="id_tipo_0" value="UP" name="tipo" /><img src="/images/thumb_up.gif"/>
<input type="radio" id="id_tipo_1" value="DOWN" name="tipo" /><img src="/images/thumb_DOWN.gif"/>
I have no clues on how to achieve this.
There is a nice solution for this issue!
A ModelChoiceField has the method label_from_instance(self, obj). This method is called for every option in the ModelChoiceField.
You can overwrite ModelChoiceField.label_from_instance with:
def label_from_instance(obj):
"""
Shows an image with the label
"""
image = conditional_escape(obj.thumbnail_image.url)
title = conditional_escape(obj.title)
label = """<img src="%s" />%s""" % (image, title)
return mark_safe(label)
Note: you need to use mark_safe, otherwise the renderer will escape the img tag. Do apply the conditional_escape to the user input values (title and url).
If you want to use a regular ChoiceField you can just add HTML to the choices parameter and add mark_safe.
You can override RadioSelect (and RadioFieldRenderer) class.
OR! you can use jquery ( or something similar) to insert your img dynamically.
$(document).ready(function(){
$("#id_tipo_0").after('<img src="/images/thumb_up.gif"/>')
$("#id_tipo_1").after('<img src="/images/thumb_down.gif"/>')
});
If you want to use Django form rendering function, you'll have to use javascript to modifiy the DOM, and this will be a mess because the names of the option are rendered just after the input tag, not enclosed in any tag...
If your form does not have any other tags, go ahead, just write your input just as in your example, carefully using the Django names and values for the radio input, add a submit button, a CSRF token and that's all, you'll be able to validate your form in the view like if it was rendered via {{form.as_p}}
I've run into a problem with using two models for my form in Django. I have two models, Animal and Family, both with a "name" field.
I use the two modelforms on my template for my form, and when it's submitted, the POST data for 'name' only returns one value.
Short of renaming the 'name' field in my models, is there any way around this?
Thanks for your help. This is my first post here.
You could make use of the prefix-argument when initializing the modelforms;
animal_form = AnimalForm(request.POST or None, prefix="animal")
family_form = FamilyForm(request.POST or None, prefix="family")
Which will output something like;
<input id="id_animal-name" type="text" />
<input id="id_family-name" type="text" />
You can get the different POST values that are under the same name with request.POST.getlist.
However, the correct value will then depend on the position of the input field in the form (I guess) and this really can't be a good idea. Change the name of the field, not in the model, but in your form class (I hope you use one).