How to assign form id to Django ModelForm? - django

I am using django-webtest to create automated functional tests for my application.
As I have multiple forms on a single web page, I'm currently using a hard-coded index to select the form of interest. For instance:
# Forms on this page are: forms[0] = Establishment form,
# forms[1]= School Form
school_form = school_page.forms[1]
school_form['phone'] = self.school_phone_number
school_form.submit(value='Submit')
I would like to use the form id instead of a hard-coded index to select the form of interest, so that the code is maintainable. But when I print school_form.id in my code, the value is None.
Template is:
<form action="" method="post" >
{% csrf_token %}
<p>
{{ establishment_form|crispy }}
<br><br>
{{ school_form|crispy }}
</p>
<button type="submit" class="btn btn-lg btn-primary">Submit</button>
I couldn't locate in the Django documentation how to assign the form id (not the form field id) to a ModelForm. Could someone help me with this?
I'm using Django 1.7, django-webtest 1.7.8, WebTest 2.0.18 and django-crispy-forms 1.4.0.

Django forms aren't responsible for outputting the form element itself. So there is nothing to be done at the form declaration level.
You can always pass an attribute from the view and use it in your template:
<form id="{{ form_id_from_view }}" action="." method="POST">

You can directly assign the id to the form element in your template.
<form id="my_id" name="some_name" action="/my/url/" method="POST">

Related

Django - do not validate the second form

I have this code snippet in template.
<form method="POST" novalidate>
{% csrf_token %}
{{ form }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>
And in forms.py there are two forms (not ModelForm, but only Form).
form searches data in first db and form2 search data in second db and displays the results. The second form has only one field and I'd like to have something like this in
a view.
if request.method == "POST":
if form.is_valid():
# extract data from the first db
if form2.is_valid()
# extract a few more data from the second db
The field in the second form is not required for the user to fill in. If the user fills it in the user gets only more data displayed.
I solved it partially with the novalidate in HTML. But what I'd like to have is the validation of the first form and the second form with its one form field can be empty.
Is there some django feature to achieve this result?
something like this?
<form method="POST">
{% csrf_token %}
{{ form.novalidate }}
{{ form2.as_p }}
<button type="submit" class="btn btn-secondary">Search</button>
</form>

How to update a single field in django?

How do I update a single field in django using html template?
I have an html page to add records. I need to make an html page only to update a single field of the model. How do I do that. And what should be the view function for it.
It's really quite simple with an UpdateView.
It takes care of building a generic ModelForm class for the model too.
class UpdateSomeFieldView(views.UpdateView):
fields = ('some_field',)
model = MyModel
For the template, all you really need there is a
<form method="post">
{% csrf_token %}
{{ form.errors }}
<table>{{ form.as_table }}</table>
<input type="submit" />
</form>

How to populate existing html form with django UpdateView?

I am trying to implement a simple UpdateView, but I want to use my own template. Using djangos auto_population is working, but not what I want, because I have lots of fields formatted differently.
<form method="post" action="#">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
But I want to use my own form template which looks like this:
edit_template.html
<form class="form-horizontal" role="form" method="POST" action="{% url 'update' pk=abc %}">
{% csrf_token %}
<input name='varX' id="varX" type="text" placeholder="" class="form-class">
<input name='varY' id="varY" type="text" placeholder="" class="form-class">
</form>
views.py
class ModelUpdate(UpdateView):
model = MyModel
fields = ['varX','varY']
Now I would like that form to be populated with my object data, but the form is empty.
UpdateView is also passing the data twice to the template: One as 'object' and one as 'mymodel'.
I also tried updating
get_context_data
by adding
context.update( model_to_dict(myModelData))
But that also does not change anything.
How can I populate my custom form using djangos class-based views?
Try this:
def get_initial(self):
initial = super().get_initial()
initial['my_form_field1'] = self.request.something
return initial
Have a look at django-widget-tweaks, you first need to check for any non field errors and then loopt through the fields one by one.
https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html
This article should cover just that

Referencing forms fields generated with Wagtail Form Builder

I have generated a simple contact form with four fields using Wagtail Form Builder. The challenge I'm having, is that I'm unable to reference the form fields with css classes individually, since I'm not sure where I should get the field id and label name from.
Here is the code that renders the form:
<h1>{{ page.title }}</h1>
{{ page.intro|richtext }}
<form action="{% pageurl page %}" method="POST" class="sky-form contact-style">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
If referencing the fields individually is not possible, what will be the other method(s) to achieve the same result?
Wagtail formbuilder creates a dynamic form - the id (name) of each field is created by the following code: str(slugify(text_type(unidecode(self.label))))
(from https://github.com/torchbox/wagtail/blob/master/wagtail/wagtailforms/models.py#L90)
So the field label is converted to ascii characters and then to a slug. For example, if you have a field name First Name it will be converted to 'first-name'.
An easy way to find out what is the actual id of the form fields that wagtail formbuilder creates is to actually output the fields in a template by enumerating them:
{% for field in form %}
{{ field }}
{% endfor %}
and then inspect the produced html code to see their actual ids (you'll see <input class="textinput textInput" id="id_first-name" maxlength="255" name="first-name" type="text"> so you'll know that the id of the field is first-name)

Django Forms to values of html <input> field

I am trying to access the values of a Bootstrap btn-group from Django and from the documentation I have found, it seems that you should use Forms in Django for such tasks.
This is what the html looks like, right now:
<div class="col-md-6">
{% for metric in metrics %}
<input name="{{ metric.name }}" type="hidden" value="0"/>
{% endfor %}
<div class="btn-group" data-toggle="buttons">
{% for metric in metrics %}
<button type="button" class="btn btn-default" data-checkbox-name="{{ metric.name }}">{{ metric.name }}</button>
{% endfor %}
</div>
</div>
How can I use forms to get the values of the input fields?
Here it is a basic example about using a form in django
views.py:
#login_required
def your_view(request): # Add this code into your view
if request.method == 'POST':
# So here you can do a loop over POST fields like this
data_list = [] # We will insert all the inputs in this array
for key in request.POST:
data_list.append(request.POST[key])
# Here you can manage the the data_list and do whatever you need
# The content of the data_list depend on your inputs
# It could be string, integer....
# YOUR VIEW CODE
template (form example):
<form action="." method="post" id="add_user_form">
{% csrf_token %}
{% for metric in metrics %}
<input type="text" name="{{ metric.name }}" placeholder="whatever you want">
{% endfor %}
<input type="submit" value="submit" class="default"/> # Submit button
</form>
{% csrf_token %} : You need to put this in every form you use
action="." : This make the post to the actual page
But anyway I strongly recommend you to check this Django Forms Documentation to unterstand better the logic, and also check the ModelForms because can save you a lot of time when you need to make a form for a model that exists in your Django Models
You are'n forced to use django forms, this is just a way to get a sort of organization.
in you views toy can get the values sent to the server by using request.GET or request.POST, depending of the method of the form.
to get a list of values you have received just do a
print request.POST
request.POST is a dictionary, so you can get any value fron them by its key:
print request.POST['<key>']