class AddRoleForm(forms.Form):
roles=forms.ModelMultipleChoiceField(queryset=Role.objects.all(),widget=forms.CheckboxSelectMultiple())
in the template :
{{ form.roles }}
the result is like this:
<ul>
<li><label for="id_roles_0"><input type="checkbox" value="1" name="roles" id="id_roles_0"> User object</label></li>
<li><label for="id_roles_1"><input type="checkbox" value="2" name="roles" id="id_roles_1"> User object</label></li>
</ul>
I want to show the role's name in each line and get the role's id in the chebox
like:
<ul>
<li><label for="id_roles_0"><input type="checkbox" value="100" name="roles" id="id_roles_0">boss</label></li>
<li><label for="id_roles_1"><input type="checkbox" value="101" name="roles" id="id_roles_1">employee</label></li>
</ul>
What should i do?
check your model 'Role'
you need add
def __unicode__(self):
return self.name
I think you this post can possibly help you.
Have a look at: Django - Render CheckboxSelectMultiple() widget individually in template (manually)
To change value parameter you have to do those steps:
Write your own CheckboxInput and overload render function. You have to change
final_attrs['value'] = force_text(value)
to something like that:
final_attrs['value'] = force_text(str(int(value) + 99))
Other parts can be copied without changes.
Write your own CheckboxSelectMultiplue and overload render function. You have to change
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
to your implementation of CheckboxInput.
Use your new widget instead of built-in.
NOTE: Parts of code may differs, because they can depends of Django version
About issue with User object: I'm not sure, but try to check your __unicode__ function.
Related
Is there a way to specify the css for an individual field and input in django crispy forms? I am using bootstrap4 and would like to use a horizontal form for a few fields in my form.
I know you can use a self.helper to set label.class and field.class but I presume that applies to all field. I only want to change the label and field class on a few of my fields.
EDIT:
I need to add css to the label that is different from the input
I'm trying to get a horizontal field inside a form like the amount field below
<div id="div_id_amount" class="row">
<label for="id_amount" class="col-form-label col-2 requiredField">
Amount<span class="asteriskField">*</span>
</label>
<div class="">
<input type="number" name="amount" step="0.01" class="numberinput form-control col-md" required="" id="id_amount">
</div>
</div>
One solution is given here:
You add the class attributes for the input field via the widget, as also explained in the django docs
You explicitly add the <label> tags with the correct class in your HTML.
Or, for the label, you can also create the following template filter:
#register.filter(is_safe=True)
def label_with_classes(field, css):
return field.label_tag(attrs={'class': css})
which you can use like this in your template after you've loaded it with {% load my_filters %}: {{ form.name|label_with_classes:"col-sm-6 col-lg-3" }}
I don't know of an easy way with crispy-forms.
You can add this in your Layout:
Field('password', id="password-field", css_class="passwordfields", title="Explanation")
You can find more details here
i want to create two same name submit in html like this
<input type="submit" name="key" value="up">
<input type="submit" name="key" value="down">
but i want to use flask-wtf to do it, i don't know how to create Class?is like this?
class NameForm(FlaskForm):
submit = SubmitField('up')
submit = SubmitField('down')
No. Doing it like that will simply overwrite the class attribute submit. Do it like this:
class NameForm(FlaskForm):
key = SubmitField('not_used_string')
Then in your html after return render_template('page.html', form=form) you render it like this:
{{ form.key(value='up', id="A1") }} # -> will render <input id="A1" name="key" type="submit" value="up">
{{ form.key(value='down', id="A2") }} # -> will render <input id="A2" name="key" type="submit" value="down">
You don't have to supply id's but if you don't they will both be key.
Note that in order to have the same name you can only have one class attribute with that name.
I'm finding it overly difficult to customize ClearableFileInput as set as the default widget in a modelForm that includes an ImageField in the model.
Particularly I don't want the Delete Checkbox that is part of the widget. I've tried customizing/overriding the rendering in a number of ways to get rid of the checkbox including setting the widget to FileInput and overriding the render method where subclassing the widget in a widgets.py file.
The simplest I can explain the problem is like this:
forms.py
class SpecImageForm(ModelForm):
orig_image = forms.ImageField(required=False, widget=forms.FileInput)
class Meta:
model = SpecImage
fields = ['orig_image',]
# The intention is to have more than one SpecImageForm once this is working but for now the
# max_num is set to 1
SpecImageFormSet = inlineformset_factory(Spec, SpecImage, form=SpecImageForm, extra=1, max_num=1)
Despite explicitly setting the FileInput against the widget it renders like this in my template - still including the checkbox which I don't think should be present using FileInput.
<fieldset>
<legend>Images</legend>
<input id="id_specimage_set-TOTAL_FORMS" name="specimage_set-TOTAL_FORMS" type="hidden" value="1" />
<input id="id_specimage_set-INITIAL_FORMS" name="specimage_set-INITIAL_FORMS" type="hidden" value="0" />
<input id="id_specimage_set-MAX_NUM_FORMS" name="specimage_set-MAX_NUM_FORMS" type="hidden" value="1" />
<ul>
<li>
<label for="id_specimage_set-0-orig_image">Orig image:</label>
<input id="id_specimage_set-0-orig_image" name="specimage_set-0-orig_image" type="file" />
</li>
<li>
<label for="id_specimage_set-0-DELETE">Delete:</label>
<input id="id_specimage_set-0-DELETE" name="specimage_set-0-DELETE" type="checkbox" />
<input id="id_specimage_set-0-id" name="specimage_set-0-id" type="hidden" />
<input id="id_specimage_set-0-car" name="specimage_set-0-car" type="hidden" />
</li>
</ul>
</fieldset>
The relevant part of the template is this:
<fieldset>
<legend>Images</legend>
{{ image_form.management_form }}
{% for form in image_form %}
<ul>
{{ form.as_ul }}
</ul>
{% endfor %}
</fieldset>
The only thing slightly different that I'm doing is using an inlineformset_factory.
I've also tried to override the rendering of a widget using widgets.py but similarly seem unable to rid myself of the defualt settings - principally based on this thread.
Any ideas or solution to rid myself of the checkbox would be gratefully received!
I think this is to do with the inlineformset_factory applying a default can_delete parameter set to true, which was present regardless of how I'd prepared the form to use with it. Simply passing can_delete=False got rid of the Delete checkbox.
SpecImageFormSet = inlineformset_factory(Spec, SpecImage, form=SpecImageForm, extra=1, max_num=1, can_delete=False)
In addition when I rendered the form on it's own (without using inlineformset_factory) there was no sign of a 'Delete checkbox'. Then I found this SO post that explained why.
Getting there.
So, I want to use a JS library called datepicker as a template for my date fields in forms.
My custom widget`s code just renders a template:
class MyDateWidget(SelectDateWidget):
def render(self, name, value, attrs=None):
template = loader.get_template('date_widget.html')
return template.render(Context({}))
and date_widget.html contains following
<div class="input-append date" id="dp-input1" data-date-format="dd-mm-yyyy">
<input class="span12" size="16" type="text" value="12-02-2012" readonly="">
<span class="add-on"><i class="icon-calendar" onclick="$('#dp-input1').datepicker();"></i></span>
</div>
this html is kind of ok, I can see the nice popup datepicker menu in my page, but for some reason request.POST (this form posts, yes) doesn`t contain the picked date. Other fields are presented into the POST data.
Apparently my widget misses some important "backend" logic.
Though this question is pretty old, I think you must add the name attribute to the input tag:
class MyDateWidget(SelectDateWidget):
def render(self, name, value, attrs=None):
template = loader.get_template('date_widget.html')
return template.render(Context({'name': name}))
And:
<div class="input-append date" id="dp-input1" data-date-format="dd-mm-yyyy">
<input class="span12" size="16" type="text" name="{{ name }}" value="12-02-2012" readonly="">
<span class="add-on"><i class="icon-calendar" onclick="$('#dp-input1').datepicker();"></i></span>
</div>
I have a view that edits an instance of model Foo. It's either called with one arg (form post) or three args (initial request to edit the object):
def edit_it(request, key1_id=-1, key2_id=-1):
where key1_id and key2_id identify the particular instance to edit. On entry, I check to see if I've been called from a form post or from a link
if request.method == 'POST':
key1_id = request.key1_id # first thing that doesn't work
key2_id = request.key2_id # (also doesn't work)
foo = Foo.objects.get(key1=key1_id, key2=key2_id)
form = Foo(request.POST, instance=foo)
...
else:
foo = Foo.objects.get(key1=key1_id, key2=key2_id)
form = Foo(instance=foo)
In my template, I explicitly insert <input type="hidden" ... > for key1_id and key2_id. So it seems reasonable that key1_id and key2_id should be in request.POST somewhere, but I've not found it poking through code, docs, and google.
Or am I completely confused and I should do this differently? I tried specifying the key[12]_id fields in the model with "widget=forms.HiddenInput", but widget doesn't work here: key1_id is a primary key and key2_id is ForeignKey whose job is just to avoid fishing for other people's objects by modifying key1_id in the URL.
The html that results (now slightly modified thanks to the suggestion to maintain the args to the post) is this:
<table>
<form action="/seededit/u=2/sh=14" method="post">
<div style='display:none'>
<input type='hidden' name='csrfmiddlewaretoken'
value='19a559c496e637cdbf3132ce8e147cc4' /></div>
[...]
<tr>
<td><input type="hidden" name="user_id" value="2" />
<input type="hidden" name="shareable_id" value="14" /></td>
<td><input type="submit" value="Submit" name="submit" /></td>
</tr>
</form>
</table>
</p>
It's not request.key2_id It's request.POST['key2_id]` request.POST is a QueryDict that acts like a dictionary, so print request.POST will show you a dictionary.
That being said, you can still use/define those fileds as HiddenInput and then use django's form validation to make sure that they are the right type/exist etc. There are loads of options when it comes to handling forms, request variables, and validation.