Issue assigning form fields in the HTML template django - django

I have a model form and I wanted to know if it is possible to take a model form and assign the name of the specific field when it is running through a for loop within the template html file.
Here is what i have in the current html template:
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{{ trans.user.username }}
{{ form.as_p }}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
here is the current form model:
class IndividualSplitTransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ['amount', 'description']
currently the format is looking like this:
omar
amount
description
hani
amount
description
assad
amount
description
tax
tip
so when i process it and i want to grab the amount assigned to each of the specific users and update a record. I want it to look something like this for easier processing in the view.
omar
omaramount
omardescription
hani
haniamount
hanidescription
assad
assadamount
assaddescription
tax
tip
so that when i am processing I can properly assign the corrent amount and description for each user when i am updating existing records with the amount.
is it possible to do that within the template itself or would i have to do it somewhere else.
UPDATED
So i tried to change my code and update it to get what i am trying to get but this is what i am getting...
Here is the html
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }}{{ field.label }}{{ field|safe }}
</div>
{% endfor %}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
and here is what I am getting.
request returs
So if you look at the image, it is still just returning the last amount and description of the three that i entered... should i just create the whole form manually in the html file....

If you wanted the username + amount or username + description, then you to change away from form.as_p, because you will get the html <p><p/> tag for each field with label preceding it.
You want to dynamically add username then do by designing your own html content of the form manually.
There is a label_suffix, but prefix is not available. Even with suffix you should be doing it at the time of creating the form object.
Update:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }} {{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}

Related

Show / hide input field or div based on RadioField choice using Flask wtf_form

I am trying to build website using Flask, and can't find solution to one problem. I am trying to hide or show input field, based on RadioFeild choice. Also, if input field showing, it have to be required. I actually have everything working, besides knowing what RadioField choice was selected. I can see the form when loading page on 127.0.0.1:5000 and I can see RadioField with 2 choices: Yes and No, but when I click on yes, there are no changes, hidden input field is still not showing. Please, help!
app.py
class MyClass(FlaskForm):
my_field = RadioField("bla-bla-bla", choices=[('Yes', 'Yes'), ('No', 'No')], validators [InputRequired()])
#app.route("/some_page")
def some_page():
form = MyClass()
return render_template("some_page.html", form=form)
_render_field.html
{% macro render_radio_field(field) %}
<div class="form__item">
<label class="form__label">{{field.label.text }}</label>
<div class="form-group">
{{ field(class_='form__input', **kwargs)|safe }}
{% for subfield in field %}
<div class="form__item">
<label>
{{ subfield }}
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
</div>
</div>
{% endmacro %}
some_page.html
{% from "_render_field.html" import render_field, render_radio_field %}
{% extends "layout.html" %}
{% block title %}My Title{% endblock %}
{% block content %}
<div style="width:600px; margin:0 auto;">
<h3>Some Text</h3>
<form class="form" action="{{url_for('some_page')}}" method="POST">
{% from "_render_field.html" import render_field, render_radio_field %}
{{ form.csrf_token }}
{{ render_field(my_field, title="", style="list-style:none") }}
{% if form.my_field.option == "Yes" %}
{{ render_field(form.some_other_StringField, placeholder="Please explain:", title="") }}
{% endif %}
<input type="submit" name="" value="login" class="form__btn">
</form>
</div>
{% endblock %}

How to create and submit multiple instances of a form on a single page?

I want 3 instance of a URL input form so I can submit up to 3 different URLs.
forms.py
class AdditemForm(forms.Form):
url = forms.URLField(
label='Add Item',
widget=forms.URLInput(
attrs={
"class": "form-control",
}))
view.py
def ItemDetail(request, pk):
listitem = comparelist.objects.get(id=pk)
if request.method == 'POST':
form = AdditemForm(request.POST)
if form.is_valid():
url = form.cleaned_data.get("url")
items.objects.create(
link=url,
name=product_name,
price=price,
store=store,
)
return HttpResponseRedirect(request.path_info)
else:
form = AdditemForm()
template = 'itemdetail.html'
context = {
"comparelist": listitem,
"form": form,
}
return render(request, template, context)
I'm using a form snippet I found in a tutorial:
{% load widget_tweaks %}
<form method="post" class="form">
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% for field in form.visible_fields %}
<div class="form-group">
{{ field.label_tag }}
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
So how do I get 3 of those forms on my page and be able to submit 3 different URLs?
I can only think of having to create 3 different form classes and paste the form snippet 3 times into the template. But that seems like a lot of unnecessary repetition.
Why "create 3 different form classes" ??? You can just create three instances of the same form.
paste the form snippet 3 times into the template
Ever heard about lists and loops ? You can put the three (or more) forms in a list and loop over it.
BUT that's actually not the best solution here - Django has Formsets for this use case.

csrf_token missing and how to get details for specific id entered by user

I am trying to display the result for the specific id entered by the user. I 'm not sure about the view.py file also. What changes should I need to make to get the desired result?
view.py file
def show(request):
if request.method == 'POST':
Num = allData.objects.only('emp_no')
data = request.POST.get('emp_no')
if data.is_valid():
for n in Num:
if n == data:
empid = data
emp = {'emp_no':data}
return render(request,'system/show.html',{'emp_no':data})
return(data.errors)
return HttpResponse("<h2>OOPS!! NO RECORD FOUND</h2>")
show.html
{% extends 'system/base.html' %}
{% load staticfiles %}
{% block body_block %}
<div class="container" "jumbotron">
<h2>Details</h2>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label class="lb" for="emp_no" >Employee No.</label>
<input type="number" name="emp_no">
<button type="submit" class="btn btn-success">SUBMIT</button>
</form>
{% for allData in emp_no %}
{{ allData.GENDER_CHOICE}}
{{ allData.first_name }}
{{ allData.last_name }}
{{ allData.birth_day }}
{{ allData.hire_date }}
{{ allData.dept_no }}
{{ allData.dept_name }}
{{ allData.salary }}
{{ allData.from_date }}
{{ allData.to_date }}
{{ allData.titles }}
{% endfor %}
</div>
{% endblock %}
Welcome to SO!
From what you have there it looks like it would be worthwhile taking a look at the Django forms documentation.
The main thing that jumps out to me is that you are trying to reuse the same template both for the form and for the data display after the form is submitted. It might be easier to separate them.
If you do want to keep one template, then you don't want to show the form if there is data and vice versa - if there is no data, then you want to show the form. It would look something like this:
{% if emp_no %}
{% for allData in emp_no %}
{{ allData.GENDER_CHOICE}}
{{ allData.first_name }}
{{ allData.last_name }}
{{ allData.birth_day }}
{{ allData.hire_date }}
{{ allData.dept_no }}
{{ allData.dept_name }}
{{ allData.salary }}
{{ allData.from_date }}
{{ allData.to_date }}
{{ allData.titles }}
{% endfor %}
{% else %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label class="lb" for="emp_no" >Employee No.</label>
<input type="number" name="emp_no">
<button type="submit" class="btn btn-success">SUBMIT</button>
</form>
{% endif %}
The title of your question also mentions csrf_token problems. You didn't give any details, but my guess is things are getting confused because you are loading the form even when you don't need it.
I will point out a few things before trying to post a solution.
Your code is not that readable because of the way you name variables. Try naming your variables in a way that tries to reflect what your code is doing.
I will suggest that you finish django tutorial if you haven't done that already. It will help you grab the core concepts of Django.
From what I understood you are trying to get an employee with a given employee number.
This is how I would do it.
In the views.py I would user render instead of HttpResponse.
def show(request):
context = {}
if request.method == 'POST':
# extract the emp no from the request
emp_no = request.POST.get('emp_no')
# get or create the employee with this emp_no
current_employee = Employee.objects.get_or_create(emp_no)
context['current_employee'] = current_employee
return render(request, 'show.html', context)
In the templates, you don't need a forloop. You are retrieving only one employee.
{% extends 'system/base.html' %}
{% load staticfiles %}
{% block body_block %}
<div class="container" "jumbotron">
<h2>Details</h2>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label class="lb" for="emp_no" >Employee No.</label>
<input type="number" name="emp_no">
<button type="submit" class="btn btn-success">SUBMIT</button>
</form>
<div>
{{ current_employee.GENDER_CHOICE}}
{{ current_employee.first_name }}
{{ current_employee.last_name }}
{{ current_employee.birth_day }}
{{ current_employee.hire_date }}
{{ current_employee.dept_no }}
{{ current_employee.dept_name }}
{{ current_employee.salary }}
{{ current_employee.from_date }}
{{ current_employee.to_date }}
{{ current_employee.titles }}
</div>
</div>
{% endblock %}

Trying to access ModelForm field modelChoice choices in Django template

I'm generating ModelForms and want some granular control over how they are output in my template. Specifically, I need to add some markup to the end of each radio button in each of my select lists.
Code:
# order-form.html
{% load catname %}
<form id = "order-form">
{% for form in forms %}
<div id="gun-{{ forloop.counter }}">
{% for field in form.fields %}
<div id="{{ field }}-item" class="item">
<h3>{{ field|catname }}</h3>
{% for choice in form.field.choices %} {# <-- Help me out here #}
{{ choice.id }}
{{ choice.title }}
{% endfor %}
</div>
{% endfor %}
{% endfor %}
<button type="submit" id="standard-gun-form-submit">Continue to next step</button>
</form>
# views.py
def get_form(request):
if request.method == 'POST':
if request.POST['gun_type'] == 'standard':
forms = [StandardGunForm(prefix=p) for p in range(0,2)]
return render_to_response('main/order-form.html', {'forms' : forms,}, RequestContext(request))
# forms.py
class StandardGunForm(ModelForm):
def __init__(self, *args, **kwargs):
super(StandardGunForm, self).__init__(*args, **kwargs)
for field in self.fields:
if isinstance(self.fields[field], ModelChoiceField):
self.fields[field].empty_label = None
class Meta:
model = BaseGun
widgets = {
'FrameTuning' : RadioSelect(),
'FrameConnection' : RadioSelect(),
}
exclude = ('price')
Endgame: markup that looks like this
<form id="foo">
<div class="category">
<div class="item">
<input type="radio" name="srsbzns" value="1">Option 1</input>
<img src="http://placekitten.com/150/150">
<p>Other foo here</p>
</div>
<div class="item">
<input type="radio" name="srsbzns" value="2">Option 2</input>
<img src="http://placekitten.com/150/150">
<p>Other foo here</p>
</div>
<div class="item">
<input type="radio" name="srsbzns" value="3">Option 3</input>
<img src="http://placekitten.com/150/150">
<p>Other foo here</p>
</div>
</div>
</form>
From the shell, this returns what I want
>>> forms = [StandardGunForm(prefix=p) for p in range(0,2)]\
>>> forms[0].fields['frame_tuning'].choices.queryset
I'm surprised this is proving so challenging!
Bonus: I have DEBUG = True and Django Debug toolbar enabled. Is it possible to dump the variables to the browser, so I can see what this stuff looks like as I drill down?
Thanks!
I had to do something similar and started down this path as well. I wanted to create table rows from a ModelChoiceField where each column had a different field of the model instance (and then I'd allow filtering the table rows via JavaScript).
I couldn't find it in the Django docs, but a quick perusal of the Django source showed the way. You can get to the queryset to access the model instances like so:
<form action="{% url 'some_view' %}" method="post">
{% csrf_token %}
{% if form.non_field_errors %}
{{ form.non_field_errors }}
{% endif %}
{% for field in form %}
{{ field.label }}
{% if field.field.choices %}
{% for model_instance in field.field.choices.queryset %}
{{ model_instance.id }}
{% endfor %}
{% else %}
{{ field }}
{% endif %}
{% if field.errors %}
{{ field.errors|striptags }}
{% endif %}
{% endfor %}
<button type="submit">Submit</button>
</form>
However, at this point we've disassembled the shiny widget (in my case a CheckboxSelectMultiple) and must re-assemble the HTML form input using template code. I found no direct way to simultaneously iterate over the ModelChoiceField to access the model instance fields and get the HTML form tags for the choices.
Maybe there's a way, but I abandoned my attempt and built my own HTML form, handling all the POST data in a view. It ended up much easier that way. ModelForms are really nice and convenient, but using them for something they weren't built for can end up being more difficult.
I figured I'd post this in case anyone is trying to do it for some other reason. Hope it helps.
Very late, but I'm reading now and this is what it worked for me
{% for field in form %}
{% for x, y in field.field.choices %}
{{x}}
{{y}}
{% endfor %}
{% endfor %}
Where "x" is the id or code, and "y" is the readable value or title.
You can access the underlying model instance for each choice:
{% for choice, label in form.field_name.field.choices %}
{{ choice.value }}
{{ choice.instance }}
{{ choice.instance.instance_attribute }}
{{ label }}
{% endfor %}
{% for choice in form.field.choices %} {# <-- Help me out here #}
{{ choice.id }}
{{ choice.title }}
{% endfor %}
Look what you're doing here, you're literally trying to access a field called "field" every time in this loop, which presumably does not exist.
You need to take the field object you're iterating through, and access the choices attribute on that.
{% for field in form.fields %}
{% for choice in field.choices %}

django change form field in .html template output

I create a form based on a model , like seen below:
class ContactSelectionForm(forms.ModelForm):
contacts = ManyToManyByLetter(Contact, field_name="first_name")
class Meta:
model = ContactSelection
exclude = ('created_by',)
When I process this view I see at the .html output a field labeled with "Contact".
Now I`m wondering whether it is possible to change this output. For example I want to name this field not "Contact" but "Selected Contacts".
This is the form processing part of the .html template:
<form action="{{ request.path }}" method="POST">
<div>
<fieldset class="module aligned">
{% for field in form.visible_fields %}
<div class="form-row">
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Save" /></p>
</fieldset>
</div>
</form>
If somebody is wondering what ManyToManyByLetter(Contact, field_name="first_name") in the form is, check out http://code.google.com/p/django-ajax-filtered-fields/ . A very helpful many2many javascript library.
Did you try setting the fields label?
(the docs)
contacts = ManyToManyByLetter(Contact, field_name="first_name", label="Selected Contacts")