Is there anything like Generic templates in django like Generic views - python

Generic view have saved lot of code for me but i still have to write templates of every model. I have same code in all template i.e
<form action="/{{type}}/{{ action }}/" method="post" enctype="multipart/form-data" >
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Submit" /></p>
</form>
i.e basically i want to have all fields from the model to add or edit.
is there any work around to have generic template automatrically

If you have template code that is identical, you can use the include tag:
{% include "foo/bar.html" %}
And the included code can be modified with variables:
{% include "name_snippet.html" with person="Jane" %}
Even if the code is different for each template (I think your example is talking about forms having different fields, not sure), you can still use includes - just make two blocks:
{% include "startform.html with some_action="post" %}
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
{{ field.field2_tag }}: {{ field2 }}
{% include "endform.html %}
There is also template inheritance, where you can define a basic template, and have all your other templates inherit from it. Inheritance is block-based, you can override blocks in the parent template with new code in the child template. It works very well.

In django, templates can be generic itself!!
You can use a diferent form for each model inside the same template using {{ form.attribute }}
Here is the django oficial doc

Look at the ModelForm helper app. It will make a form from any model which can then be used in a simple form template.

Related

How to add an attribute to the form tag itself and not just a field in Django?

I am having trouble stopping bots filling in spam while letting through legit users. I have a honeypot field with autocomplete="off" attribute but it doesn't seem to be working. From what i've read, the best cross browser solution is to add autocomplete="false" to the main form tag itself, e.g. <form autocomplete="false">...</form>. What is the best way to do this in Django?
Just do that in your template where the form is added.
In a template you'd typically do something like;
<form autocomplete="false">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.label }}
{{ field }}
{{ field.help_text }}
{% endfor %}
So just add whatever you want to the form tag.
You should probably also have a look at including recaptcha if you've got spam problems.
And remember that v3 doesn't require any selecting street lights etc
https://pypi.org/project/django-recaptcha/

Pass arbitrary data from a FlaskForm object to the template

While building a small Flask based web app, I came across the need to pass arbitrary data from a Form Field object to the template where it's being rendered. However, I can't seem to find a way to do this.
The only place I think I could add such data was to the kwargs property of WTForms Field objects, but then I seem to have no way to access those properties from the template.
In case you're wondering what I'm trying to accomplish, I'm writing a template macro to ease form rendering, and I need to pass some extra data from the Form fields objects - mostly layout related, but which will not be HTML attributes for the fields themselves (which is what kwargs is designed for).
I found an answer here but it's not an answer per se but I comment.
Quoting Crast:
The description keyword argument of WTForms fields is allowed to be set at field construction, and is not inspected, just copied directly onto the field, and thus can be any value, not just a string, even a custom attribute. If you want to carry over your own metadata, you can simply use this to carry over any data you may want: TextField(..., description={'placeholder': foo', 'class': bar} (or even a custom class) then use this attribute in your template for any special metadata you want.
Yes, I know about separating content and presentation and the purpose of the description property isn't really intended for this kind of use, but it's the only way I found to pass data back to the template where I use a macro to render forms.
To access the passed data inside description from the template I did something like this:
{% macro render_create_form(form, form_title, enctype=None) %}
<h2>{{ form_title }}</h2>
<form action="" method="post"{% if enctype %} enctype="{{ enctype }}"{% endif %}>
{{ form.hidden_tag() }}
{% for field in form if not field.name == 'csrf_token' %}
{% set class_name = field.description.class %}
{% if field.type == "StringField" or field.type == "PasswordField" or field.type == "BooleanField" or field.type == "SelectField" %}
<div class="{{ class_name }}">{{ field.label }} {{ field }}</div>
{% elif field.type == "NumberField" %}
<div class="{{ class_name }}">{{ field.label }} {{ field(type='number', min=field.description.min, max=field.description.max, placeholder=field.description.placeholder) }}</div>
{% elif field.type == "HiddenField" %}
{{ field }}
{% elif field.type == "SubmitField" %}
<div class="{{ class_name }}">{{ field }}</div>
{% endif %}
{% endfor %}
</form>
{% endmacro %}

How can I show a specific django field in html?

So I want to do what the title says and I don't know how since I'm new at this.
<p>{{ form.description }}</p>
That's the way I show information from different models in a listing using
{% for form in forms %}
But I want to show the description of an specific object.
Thanks in advance.
<form method="post" novalidate>{% csrf_token %}
{{ form.non_field_errors }}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field.errors }}
{{ hidden_field }}
{% endfor %}
<table border="1">
{% for field in form.visible_fields %}
<tr>
<th>{{ field.label_tag }}</th>
<td>
{{ field.errors }}
{{ field }}
{{ field.help_text }}
</td>
</tr>
{% endfor %}
Look this article: [link][1]https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html
Usually django templates will be filled with the data rendered from the django views as dictionary and these will be callable in templates using django template tags "{{tag_name}}"
Here you will be rendering all the forms as a list inside the dictionary so you can show each form by looping it.
{% for form in forms %}
{{form.description}}
{% endfor %}
Like this, you can show each form's data. Instead of this if you only want to show a specific form's data then the proper way is to render the view with the specific form's data and show data in template using the template tag {{form.description}}
Check the django documentation : https://docs.djangoproject.com/en/2.1/topics/templates/

WTForms render_field() method reference for-loop variables

I'm using Flask to create a web app. I'm trying to create a form using Flask-WTForms by iterating through a list passed in the render_template() method. However, I can't reference the variable in the for-loop inside the template.
View
class FormExample(Form):
category1 = StringField("Category 1")
category2 = StringField("Category 2")
categories = ['category1', 'category2']
def form():
form = FormExample(request.form)
return_template("form.html", categories=categories, form=form)
_formhelpers.html (suggested to use under the docs)
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
{{ error }}
{% endfor %}
{% endif %}
</dd>
{% endmacro %}
Template (form.html)
<form method="POST">
{% for category in categories %}
{{render_field(form.category)}}
{% endfor %}
</form>
When trying to reference form.category in form.html I'm given the following error through the Flask debugger:
jinja2.exceptions.UndefinedError: '__main__.EvaluateCaseForm object' has no attribute 'category'
I've already looked at the official documentation here and couldn't find the answer. I've also tried referencing {{render_field({{ form.category }})}}, {{render_field(form.{{category}})}}, and {{render_field({% form.category %})}}
Is there a way to reference the for-loop variable category inside the render_field() method?
WTForms uses the __getitem__ protocol to allow fields can be accessed like dictionary values, for example form[fieldname].
So in your code, replace form.category with form[category]:
<form method="POST">
{% for category in categories %}
{{ render_field(form[category]) }}
{% endfor %}
</form>
Is there a way to reference the for-loop variable category inside the render_field() method?
Yup:
{% for category in categories %}
{{render_field(category)}}
{% endfor %}

How to style django-multiselectfield with CSS

I am using 'django-multiselectfield' in my model form so users can select multiple 'areas' in my form. What I want to know now is how can I style the multiselectfield using css.
I have tried simply adding a class to the form field in my template like I normally do with all the other types of model fields, but no luck:
{% render_field form.area class="area" %}
Any help would be much appreciated.
This is described in `django-multiselectfield' documentation. Specifically,
It is possible to customize the HTML of this widget in your form template. To do so, you will need to loop through form {field}.field.choices. Here is an example that displays the field label underneath/after the checkbox for a MultiSelectField called providers:
Here is a example of what i did.
{% for field in form %}
<div class="fieldWrapper">{{ field.errors }}
<input type="{{ field.field.widget.input_type }}" name="{{ field.html_name }}" id="{{field.id_for_label}}" class="col-12 input-login" placeholder="{{field.label}}" >
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
Now you can customise the field as if it is a simple html input field.
This page has a wonderful detailed explanation. Kudos to Vitor
------edit-----
Almost forgot. This is the example for normal forms. You have to go through the official docs of django-multiselectfield to get field attribute names, and replace the respective attributes
I suggest you render the form manually and loop through it.
Say you have a Choice model with a foreignkey to a Question model, you could do it like this:
<form class="qform" action="" method="post">
{% csrf_token %}
<p class="title">{{ form.question }}</p>
{% for choice in form.choice_set.all %}
<input type="checkbox" name="{{ choice }}" id="{{ choice }}{{ forloop.counter }}"
value="{{ choice.id }}">
<label for="{{ choice }}{{ forloop.counter }}">{{ choice }}</label>
{% endfor %}
</form>
You can reference the input and label in your style.css like:
input[type="checkbox"]{
some: stuffs...;
}
label {
some: stuffs...;
}
I hope this helps.

Categories

Resources