I have the following radio button html using django widget tweaks (i do not have to use this library and open to using whatever method works):
{% for choice in seeking_form2.disaster_recovery %}
<div class="radio radio-primary radio-inline">
{{ choice.tag|attr:"required" }}
<label for='{{ seeking_form2.disaster_recovery.auto_id }}_{{ forloop.counter0 }}'>{{ choice.choice_label }}</label>
</div>
{% endfor %}
Which should create radios that look like this:
<input id="id_disaster_recovery" name="disaster_recovery" type="radio" value="2" required>
My model looks like:
BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
disaster_recovery = models.BooleanField(choices=BOOL_CHOICES, default=False, )
My form looks like:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'disaster_recovery': forms.RadioSelect(),
}
I get the error:
'SafeText' object has no attribute 'as_widget'
If i understand your problem correctly, you should be overriding this in the form, rather than at the template, or the models.
class MyModelForm(..):
disaster_recovery = forms.ChoiceField(choices=BOOL_CHOICES, widget=forms.RadioSelect(), required=True) #Default is dropdown
Now, you could simplify your HTML to render the radiobuttons.
Some more context on this can be found here
To add the HTML required attribute, to your existing form, you can do:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'disaster_recovery': forms.RadioSelect(attrs={"required": "required"}),
}
Here is the relevant documentation on the custom attributes
Related
I created a Date Picker using Django and Bootstrap. When clicking on the calendar field on the right of the input field, however, the calendar jumps to a default of: 06/Fr/yyyy. I tried setting the todayBtn attribute to True but that produced an error. Example can be seen on the following image:
My models.py:
class TimeInterval(models.Model):
time_interval = models.DateField()
forms.py:
from .models import TimeInterval
from bootstrap_datepicker_plus import DatePickerInput
class TimeIntervalForm(forms.ModelForm):
date = forms.DateField(
widget=DatePickerInput(
options={
"format": "mm/dd/yyyy",
# "todayHighlight": True,
# "todayBtn": True,
}
)
)
class Meta:
model = TimeInterval
fields = '__all__'
views.py:
def datepicker_form_view(request):
return render(request, "datepicker_form.html", {
"time_interval_form": TimeIntervalForm(),
})
And my HTML file:
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
<form action="." method="POST">{% csrf_token %}
{% bootstrap_form time_interval_form %}
{{time_interval_form.media }}
<input type="submit" value="Submit">
</form>
I came across a similar question about the todayHighlight attribute but there the OP used JavaScript/jQuery, hence it was advised that he added that attribute using a jQuery select. I feel that in my case, expanding the HTML code with a <script> section and a jQuery selection just to have that one attribute working is an overkill - there must be a more convenient way to go about this that I'm not aware of.
Try something like this
date = forms.DateTimeField(error_messages={'invalid': 'Wrong date.'},
required=False, widget=DateInput(attrs={
'class': 'datepicker form-control input-sm ',
'data-trigger': 'focus'}))
or
date = forms.DateTimeField(required=False,
widget=DateInput(attrs={'class': 'form-control input-sm'},
format=('%Y-%m-%d')))
I have a from containing some fields, but my css class applies to all the fileds except the EmailField. I've also tried sender.widget.attrs.update({'class':"contatct-form"}) and it still doesn't work (just change the size of field). Does anybody knows what the problem is? as all of my searches were unsuccessful.
form:
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(initial='Your name', max_length=100)
sender = forms.EmailField()
#sender.widget.attrs.update({'class':"contatct-form"})
message = forms.CharField(widget=forms.Textarea)
template:
<div class="contatct-form">
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="send" />
</form>
</div>
The problem you have probably is because you have not assigned any widget to your EmailField(), change to this (like #Todor said) should work:
...
sender = forms.EmailField(
widget=forms.EmailInput(attrs={'class': 'contatct-form'})
)
If this doesn't work for whatever reason (probably wrong css styling), you can just change the styling in your css/class directly like so:
div.contatct-form form input[type=email] {
/* your changes here... */
}
Hope this helps.
We have to do that in the init method for one field or all fields with for loop.
class NameForm(forms.Form):
def __init__(*args, **kwargs):
super(NameForm, self).__init__(*args, **kwargs)
self.fields['sender'].widget.attrs.update({'class':"contatct-form"})
I'd like to create a drop down list in an HTML template that draws data from a Django database. Is there anyway I can code it in the <option value...>?
The examples below work perfectly fine with the databases you create on your own. The problem is, that I need to make use of the username field from django.contrib.auth.models import User.
For example - you have a cars list in Template context. You can do something like this, if I understand you correctly:
<form>
<select name="cars">
{% for car in cars%}
<option value={{ car.name }}>{{ car.name }}</option>
{% endfor %}
</select>
<input type="submit" value="Submit">
</form>
Describe your model and your form as well. It's pretty simple in Django. If you have a form and the form is passed to the template, you can render the form as follows:
{{ form.as_p }}
Model example:
from django.db import models
# Your model choices
class SampleCategory(models.Model):
title = models.CharField(max_length=255)
# Your sample model that uses the model with choices
class SampleModel(models.Model):
category = models.ForeignKey(SampleCategory)
Form example:
from django import forms
from yourapp.models import SampleModel
class SampleModelForm(forms.ModelForm):
class Meta:
model = SampleModel
Crispy forms currently shows my password field as clear text. I have tried the following but I still cannot get it to use type=password.
Fieldset(
'Enter a password.',
PrependedText('password', '<i class="fa fa-key"></i>',
placeholder='Password',
autocomplete='off',
widget=forms.PasswordInput,
),
),
I have also tired type="password" with no effect.
I get no error.
I'm 99.9% positive that you missed adding the widget to the form field declaration. You should have something like this in order to display a password field:
class MyForm(forms.Form):
...
password = forms.CharField(widget=forms.PasswordInput)
...
And the layout should be as simple as:
Layout(
PrependedText('password', '#', placeholder="password", autocomplete='off')
)
The widget= keyword argument is defined on the Django's forms.CharField constructor and not on the django-cryspy-forms' bootstrap.PrependedText constructor.
You can find more information on Django forms fields here.
UPDATE
If you have a model form, it's being constructed from your model, either automatically (eg using the admin views), by using modelform_factory or by defining the ModelForm yourself. Here is an example of the 3rd approach.
class MyModelForm(forms.ModelForm):
class Meta:
fields = (... fields you want to include in the form ...)
password = forms.CharField(widget=forms.PasswordInput, ...)
Please note that by providing your model form field override, you'll have to also provide attributes like label, help_text (and such) because they will not be automatically copied from the model field.
I never had good luck with crispy-forms and formsets, so I just use forms directly in templates. See if that works:
<form method="post">{% csrf_token %}
{{ formset.management_form|crispy }}
{% for form in formset %}
<input id="id_form-{{ forloop.counter0 }}-id" name="form-{{ forloop.counter0 }}-id" type="hidden" value="{{ form.instance.pk }}"/>
{{ form|crispy }}
{% endfor %}
</form>
You need to define PasswordInput.
class YourForm(forms.ModelForm):
password = forms.CharField(label='Enter Password',widget=forms.PasswordInput(attrs={'placeholder': 'alphanumeric password'}))
I would like to add a custom field which can provide additional properties for handling the individual output of in a template. For instance here's my class:
class CustomField(CharField):
suffix = "things"
And my accompanying field.html where I've added the field.suffix block:
<div class="controlGroup clearfix {% if field.errors %}error{% endif %}">
<label class="controlLabel" for="{{ field.auto_id }}">{{ field.label }}</label>
<div class="controls">
{{ field }}
{% if field.suffix %}
<span class="suffix">{{ field.suffix }}</span>
{% endif %}
{% if field.errors %}
<span class="helpInline">{{ field.errors }}</span>
{% endif %}
</div>
</div>
Unfortunately the suffix block simply doesn't output.
EDIT: To clarify, both current answers below are targeted at adding widget attributes. I'm actually trying to add a custom string for use in the template, not a custom CSS class.
For your simple example, you can override the attrs dictionary of the widget that you use in for your form field, you don't need to create a custom field.
class YourForm(forms.Form):
some_field = forms.CharField(widget=forms.TextInput(attrs={'class': 'suffix'})
If you really want to create a custom field, you need to create a custom widget and control the render method. Depending in what type of form control you want to render, you inherit your custom widget from the equivalent provided by django.
Attributes can be passed to form fields by two ways. I have given the example code below.
class ArticleForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'field1' : forms.TextInput(attrs = {'class': 'suffix'}),
'field2' : forms.TextInput(attrs = {'class': 'suffix'}),
}
OR
class ArticleForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kw):
super(forms.ModelForm, self).__init__(*args, **kw)
self.fields['field1'].widget.attrs['class'] = 'suffix'
self.fields['field2'].widget.attrs['class'] = 'suffix'
You can use widgets as given in first example or in init as given in second example. Both will work.
EDIT: Any attribute can be passed to the django form field using the above example.
I eventually did this by creating my own widget:
class UsernameInput(TextInput):
"""
Creates a widget specifically for appending the username suffix as a label
""" 9
def render(self, name, value, attrs=None):
widget = super(UsernameInput, self).render(name, value, attrs)
widget += u'<span class="field-suffix">#%s</span>' % USERNAME_DOMAIN_PART
return mark_safe(widget)
And then in my signup form by specifying the widget like so:
username = forms.EmailField(label="Preferred Username",
widget=UsernameInput(),
error_messages={'invalid': "Please enter a valid email address"})