Render only fields in a Django inline_formset - python

I want to render only fields in a Django inline_formset.
This is my template:
<div id="storage">
<h1>Storage</h1>
{% for form in storage_formset %}
<div class="form-group">
<label class="col-sm-2 control-label">{{ form.help_texts }}</label>
<div class="col-sm-10">
{{ form.errors }}
{{ form }}
</div>
</div>
{% endfor %}
</div>
And this is my form:
help = {'field1' : "help1", 'field2' : "help2"}
StorageFormSet = inlineformset_factory(WorkOrder, Storage, min_num=0,
max_num=2, validate_min=True, validate_max=True, extra=1, help_texts=help,
fields=('field1', 'field2'))
This one works, but when it renders, it renders everything (field and field name) in the form and I want it to only render the field. Other thing is that the help_texts don't work (I don't know if I'm using it right).
If I use:
{{ form.field1 }}
It renders field1, but I want to do it dynamically, so I don't have to repeat again and again.
And if I use:
{{ form.fields }}
It renders a bunch of code
OrderedDict(
[('field1', <django.forms.fields.TypedChoiceField object at 0x7f8f6409c890>),
('field2', <django.forms.fields.IntegerField object at 0x7f8f6409c650>),
(u'id', <django.forms.models.ModelChoiceField object at 0x7f8f6409c1d0>),
(u'DELETE', <django.forms.fields.BooleanField object at 0x7f8f6409cc90>),
('parent_field', <django.forms.models.InlineForeignKeyField object at 0x7f8f659c4e10>)])
I don't know what else to do.
Thank you if you can help me.

I modified your code to only render fields and their associated help texts:
<div id="storage">
<h1>Storage</h1>
{% for form in storage_formset %}
<div class="form-group">
<label class="col-sm-2 control-label">{{ form.help_texts }}</label>
<div class="col-sm-10">
{{ form.errors }}
{% for field in form %}
{{ field }} {{ field.help_text }}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
For more information about accessing form fields in a template visit the docs.

Related

rendering forms into HMTL using django-easy-select2

I am using django-easy-select2 to handle the entering of data into several manytomanyfields within a model - titled Engagement.
I am using bootstrap and crispy forms to render the Engagement form to HTML.
The rendering is broadly working as expected/required. However, the size of form fields for manytomany data are initially very small and require data to the selected/entered, before they expand. Once data is entered the fields do expand. But, I would like these fields to initially render as the size set by bootstrap.
For example, I've set bootstrap as col-6, but the initial render of the manytomany is only col-1 or even less. When data is entered that field will expand up to col-6 and no further, which good, but I would like the field to start at col-6, even with no data.
Relevant code is below.
engagements.view:
class EngagementCreateView(CreateView):
model = Engagement
form_class = select2_modelform(Engagement, attrs={'width': 'auto'}) # this sets the widths of the field
template_name = "engagements/engagement_create.html"
def form_valid(self, form):
print(form.cleaned_data)
return super().form_valid(form)
create engagement template
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<h4>{% if form.instance.pk %}Edit engagement{% else %}Create new engagement{% endif%}</h4>
<div class="form-group">
<form method="post" novalidate>
{% csrf_token %}
<div class="row mt-1">
<div class="col-6"> # I'm rendering the width of fields here
{{ form.date|as_crispy_field }}
{{ form.projects|as_crispy_field }}
{{ form.stakeholders|as_crispy_field }}
{{ form.ppdds|as_crispy_field }}
</div>
<div class="col-6">
{{ form.follow_up_date|as_crispy_field }}
{{ form.engagement_types|as_crispy_field }}
{{ form.engagement_workstreams|as_crispy_field }}
</div>
</div>
<div class="row mt-1">
<div class="col-lg">
{{ form.summary|as_crispy_field }}
</div>
</div>
<br>
<input class="btn btn-primary" type="submit"
value="{% if form.instance.pk %}Save{% else %}Create{% endif%}">
<a class="btn btn-primary" href="../">Cancel</a></p>
</form>
</div>
{% endblock %}
I think the most relevant part of the django-easy_select2 documentation is here https://django-easy-select2.readthedocs.io/en/latest/usage.html.

Django input login for an admin

How can I add attribute autocomplete="off" to the input login template form for an admin?
I'm find this in the login.html template but can't find where is the form template
<div class="form-row">
{{ form.username.errors }}
{{ form.username.label_tag }} {{ form.username }}
</div>
If you need to change behavior based on whether or not the user is admin/staff:
{% if request.user.is_staff %}
<form autocomplete="off" method="post" action="action_name">
<input autocomplete="off" name="hidden" type="text" style="display:none;">
{% else %}
<form method="post" action="action_name">
{% endif %}
<div class="form-row">
And complete the rest of the form as you would.
Reference for the form and input tags to turn autocomplete off (note autocomplete is "off" in the input tag as per testing in comments):
https://gist.github.com/niksumeiko/360164708c3b326bd1c8

edit django form widget rendering

I have a Django form where one of the fields is defined as:
widgets = {
'name': forms.CheckboxSelectMultiple()
}
The template renders them in a loop with:
{% for field in form %}
<fieldset class="article-form__field">
{{ field.label_tag }} {{ field }}
</fieldset>
{% endfor %}
This is rendered as:
<fieldset class="article-form__field">
<label for="category-name_0">Category:</label>
<ul id="category-name">
<li><label for="category-name_0"><input id="category-name_0" name="category-name" type="checkbox" value="GEN" /> General information</label></li>
<li><label for="category-name_1"><input id="category-name_1" name="category-name" type="checkbox" value="FOO" /> Food and drinks</label></li>
</ul>
</fieldset>
In short: <label><input></label>. However, I would like the output to be <label></label><input>.
Is that possible, and if so, how?
Full code is here.
{% for field in form %}
<fieldset class="article-form__field">
{% if field.name != "category-name" %}
{{ field.label_tag }} {{ field }}
{% else %}
{{ field.label_tag }}
<ul id={{ field.auto_id }}>
{% for checkbox in field %}
<li>
<label for="{{ checkbox.id_for_label }}">
{{ checkbox.choice_label }}
</label>
{{ checkbox.tag }}
</li>
{% endfor %}
</ul>
{% endif %}
</fieldset>
{% endfor %}
CheckboxSelectMultiple
RadioSelect (how to customize rendering is described here)

Styling forms using Django and Bootstrap

Okay, so I've created a simple purchase form which makes use of some custom form fields. I've rendered a simple form to test if it works properly, and it does, as shown below.
<form id="category_form" method="post" action="/purchase/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Make purchase" />
</form>
Now, I wish to style it to Bootstrap 3. I've managed to style it with no problems using the django widget tweaks package. However, when I submit the form, I get this error 'NoneType' object has no attribute 'replace' I've tried it without the widget tweaks and I still get the same error.
Any ideas why this may be the case? The original form works fine unstyled, but as soon as I style it I get the above error. Now if my understanding is correct, Django takes one field and styles corresponding fields the same, but, some of my field types are different. i.e. dropdowns and text boxes, which can't be styled the same way. I'm not sure what the best way around this is.
views.py
def checkout(request):
if request.method == 'POST':
form = PurchaseForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request) # Change this to point to the confirmation page
else:
print (form.errors)
else:
form = PurchaseForm()
return render(request, 'ticket/checkout.html', {'form': form})
checkout.html
<form class="form-horizontal" method="post" action="/cart/checkout/">
{% csrf_token %}
<fieldset>
<!-- Form Name -->
<legend>Card Details</legend>
<!-- Select Basic -->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-type">{{ form.payment_type.help_text }}</label>
<div class="col-sm-9">
{{ form.payment_type|attr:"id:card-type"|attr:"name:card-type"|attr:"class:form-control" }}
{{ form.error }}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-name">{{ form.card_name.help_text }}</label>
<div class="col-sm-9">
{{ form.card_name|attr:"id:card-name"|attr:"name:card-name"|attr:"type:text"|attr:"placeholder:Card Holder's Name"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-number">{{ form.card_number.help_text }}</label>
<div class="col-sm-9">
{{ form.card_number|attr:"id:card-number"|attr:"name:card-number"|attr:"type:text"|attr:"placeholder:Credit / Debit card number"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-sm-3 control-label" for="expiry-date">{{ form.expiry_date.help_text }}</label>
<div class="col-sm-4">
{{ form.expiry_date|attr:"id:expiry-date"|attr:"name:expiry-date"|attr:"class:form-control col-sm-4" }}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="cvv-number">{{ form.security_code.help_text }}</label>
<div class="col-sm-9">
{{ form.security_code|attr:"id:cvv-number"|attr:"name:cvv-number"|attr:"type:text"|attr:"placeholder:Security Code"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="date">{{ form.date.help_text }}</label>
<div class="col-sm-9">
{{ form.date|attr:"id:date"|attr:"name:date"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="Purchase"></label>
<div class="col-md-8">
<button id="Purchase" name="Purchase" class="btn btn-success">Purchase</button>
<button id="Cancel" name="Cancel" class="btn btn-inverse">Cancel</button>
</div>
</div>
</fieldset>
I would suggest using the python package django-bootstrap3 to style your forms. It can be found at https://github.com/dyve/django-bootstrap3
Hope this helps!
I am not sure whether I understand your question correctly. However I noticed that 1. there seems no tag in your form.
2. maybe you can use plain html instead of other tag( {{ form.security_code|attr:"id:cvv-number"|attr:"name:cvv-number" ****}} ), such as
3. to validate form, you may try to write something like :
{% if form.password.errors %}
{% for error in form.password.errors %} {{ error}} {% endfor %} {% endif %}
Hope you figure out this problem as soon as possible.

Django forms adding <div> after form field

Below is my form code :
class FMessage(forms.Form):
From = forms.CharField()
To = forms.CharField()
Subject = forms.CharField()
Message = forms.CharField()
and this is my html code:
<form method='POST' action='.'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit'>
</form>
The code works fine by displaying forms and has not any issue in functionality, but now I need to wrap my form fields in html by a div like this:
<div id='mydiv'>
<input ... />
<div>
How can I fix it?
Seems like you do not really want to use the inbuilt <p> or <table> wrapped forms and rather want to display the fields wrapped within a <div>'s. You can simply iterate over fields in the form as follows.
{% if form %}
<!-- Form Errors -->
{% if form.errors %}
<ul class="errors">
{% for error in form.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<!-- Display Form -->
<form>
{% csrf_token %}
{% for field in form %}
<div class="mydiv">
<label class="mylabel">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
</form>
{% endif %}
Dont render the form by using form.as_p. You need to show each field of the form, for example, by using form.to. By using this way, you can wrap the field 'to' into a div
<div>{{ form.To}} </div>
For more detail, view this link

Categories