I am relearning django/python recently and trying to build an app to manage a season ticket draft between friends. I've become stuck while searching for this answer, could be my phrasing, but I'm trying to understand how to pass a value from one template to another. Here is an example of what I am doing.
views.py
def home_page_view(request):
sessions = DraftSession.objects.filter(session_status="ACTIVE")
return render(request, "index/index.html", {
'arena_mappings': ARENA_MAPPINGS,
'team_mappings': TEAM_MAPPINGS,
'sessions': sessions,
})
index.html
{% for session in sessions %}
<tr>
<td> {{ session.season_year }} </td>
<td> {{ team_mappings|get_item:session.home_team }} </td>
<td> {{ arena_mappings|get_item:session.home_team }} </td>
<td> {{ session.create_date }} </td>
<td> {{ session.session_owner }} </td>
<td> <button type="button" class="btn btn-primary">Join Now!</button> </td>
</tr>
{% endfor %}
Using the button in the last column I want the user to be able to go to a new page that has awareness of the row that was selected, my assumption is this would be passed in via the pk for the db row. I've setup the view, urls, etc; just lost on how to pass the selection on the the new page. Appreciate any help!
You are correct in your assumption. You just need to specify the url name in your href and pass in the parameter using the url template tag.
<td><a href=“{% url ‘session-view’ session.id %}” class=“btn btn-primary”>Join now!</a></td>
Related
I have a Search form that includes the query box, some checkbox items, and a start and end date. I am getting my information when I enter a query, so I know it is performing the search_results action, but the start and end date is not getting validated at all. I have yet to add the code to handle the start and end date in my results, but the issue is there is no client side validation happening on the form.
My form looks like this:
class SearchForm(forms.Form):
q = forms.CharField(max_length=64,required=False)
service_choices = forms.MultipleChoiceField(
required=True,
widget=forms.CheckboxSelectMultiple,
choices=CustomUser.SERVICE_CHOICES,
)
start_date = forms.DateField(required=False)
end_date = forms.DateField(required=False)
I tried using Class Based View, but did not get any fields at all, so I
tried using a function based view to get my search criteria.
The view looks like:
def get_search(request):
form = SearchForm()
return render(request, 'get_search.html', {'form':form})
My template is:
<!-- templates/get_search.html -->
{% extends "base.html" %}
{% block title %}Search{% endblock title %}
{% block content %}
{% if user.is_authenticated %}
<br><br>
<TABLE BORDER="0" WIDTH="100%">
<TR>
<TD ALIGN="Left"><B>Track X - search</B></TD>
<TD ALIGN="Center"><B>User: {{ user }}</B></TD>
<TD ALIGN="Right"><B>Service: {{ user.service }}</B></TD>
</TR>
</TABLE>
<form action="{% url 'search_results' %}" method="get"">
{% csrf_token %}
<TABLE BGCOLOR="#66CCCC" Border="2" WIDTH="100%">
<TR>
<TD ALIGN="Left" WIDTH="100"> Services:</TD>
<TD ALIGN="Right">Search expression:</TD>
<TD ALIGN="Left">
{{ form.q }}
<button type="submit" name="submit">Search TrackX</button>
</TD>
</TR>
<TR>
<TD WIDTH="100"> {{ form.service_choices }} </TD>
<TD COLSPAN="2" ALIGN="Center"> Start Date: {{ form.start_date }}
End Date: {{ form.end_date }}</TD>
</TR>
</TABLE>
</form>
{% else %}
<p>You are not logged in</p>
Log In |
Sign Up
{% endif %}
{% endblock content %}
The Search_results view just uses the query to build some Q Filter
queries, and it seems to be working correctly.
It originally used a GET Method, and was passing the parameters into the search results view just fine. It just doesn't validate the dates (or anything else I assume) before passing the parameters into the view.
Can anyone tell me what am I missing here?
As I see on the view that your posted, you are not actually checking if the form is valid, you can do that by using:
if request.method == 'POST':
form = SearchForm(request.POST)
form.is_valid()
This method will validate all your fields, and return the boolean value representing if its valid or not.
I saw where I can Have a page break in a easy pdf html template saying
<p class="pb"></p>
That is great, but I am trying to run a report where it page breaks and puts a table header every so many lines, with special consideration for the first page. Is there anyway to do this?
This is the view I am calling my html from:
class InvoiceReportIDPDF(PDFTemplateView):
#template_name = 'ipaswdb/provider/report/provider_profile.html'
template_name = 'ipaswdb/invoice/report/invoice_report_pdf.html'
def get_context_data(self, **kwargs):
context = super(InvoiceReportIDPDF, self).get_context_data(pagesize='LetterSize',title='Invoice',**kwargs)
#print "provider id: ", kwargs['pk']
self.download_filename = 'invoice-report-' + kwargs['pk'] + '.pdf'
res = build_invoice_printout_models(kwargs['pk'])
#res = build_invoice_printout_models('all')
return context
So I can print this invoice but the line items just run from one page to the next with no nice header at the top of the next page (for when same invoice)...
I can't use variables in the html page to count using the template and I thought Id get slick and when I build the items I send to the webpage to put in a field for a page break.
So when I build my object I send to the view context I have like:
invoiceItem['pagebreak'] = None
if lineCount > xmany:
invoiceItem['pagebreak'] = 'YES'
Then in the html:
{% if invoice.items %}
{% for item in invoice.items %}
<tr>
<td> {{ item.name}} - {{ item.provspecialty }} </td>
<td> Current Dues </td>
<td> </td>
<td> ${{ item.dues }} </td>
</tr>
<tr>
<td></td>
<td> {{ item.desc }} </td>
<td> ${{ item.adjustments}}</td>
<td></td>
</tr>
{% if item.pagebreak %}
<p class="pb"> </p> <!-- this didn't work right at all -->
<!-- just sent a bunch of blank lines then 5 pages down tried to work-->
{% endif %}
{% endfor %}
{% endif %}
I wish it just 'knew' where the bottom of the page was to make the break and add a new header...
I've been playing around with Django forms and it's a bit of a headache. I came to a point where I can display my form properly but I only want to edit part of it's data, not all of them.
Specifically: I have a Product model that has a title and a featured bool field. I want a form that displays all the products names with a tickbox next to it. The user is able to edit the featured property of each Product on the same form, but only that! My problem is that with the current setup, the displayed title is also an input field, not a simple text. If I change the template to display {{ productForm.title.value }} instead of {{ productForm.title }} it displays it as a text but the form failes the validation (It requires the title to have a value, since it cannot be null).
Model is plain simple, title and featured fields with CharField and BooleanField types. Validation branch is also not taken care of in the sample but "is_valid()" returns false.
views.py
def featured_product(request):
FeaturedProductFormSet = modelformset_factory(Product, fields=('title', 'featured'))
if request.method == "POST":
productForms = FeaturedProductFormSet(request.POST)
if productForms.is_valid():
productForms.save()
return redirect('/admin/')
else:
productForms = FeaturedProductFormSet()
return render_to_response(
'vetco_app/featured_products.html',
{
'productForms': productForms,
},
context_instance=RequestContext(request)
)
featured_products.html
<form action="" method="post">
<table>
<thead>
<th>
Termék neve
</th>
<th>
Kiemelt
</th>
</thead>
<tbody>
{% for productForm in productForms %}
{% if not forloop.last %}
<tr>
<td>
{{ productForm.id }}
{{ productForm.title }}
</td>
<td>
{{ productForm.featured }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<p>
{{ productForms.management_form }}
{% csrf_token %}
<button type="submit" name="action" value="Save">Save</button>
</p>
How to make it display only the text of the title without the need to validate it?
Simply provide context:
from django.template import RequestContext
context = RequestContext(request, {"your_model":your_model")
now in templates just write:
{{ your_model.some_attribute }}
Trying to create a Display in Django, which would look like this.
link: http://i47.tinypic.com/2lk2mw2.png
the number of fruits everyday is dynamic and different everyday.
the comment field is to be editable by the admin. the input would
then be used to update the row in the database
problem: so far I'm uncertain about how to go about allowing users to edit the comment column and present the changes in the database
**
fruits.html
**
{% for item in nodes %}
<tr>
<td class = "tablebord"><a href ="/nodes/node/{{ item.nodeid }}/">{{
item.nodeid }}</a></td>
<td class = "tablebord">{{ item.lastseen }} </td>
<td class = "tablebord"><div contenteditable>{{ item.comment }} <p>
<form action="" method="get">
<input type="text" name="q">
<input type="submit" value="test">
</form>
</p> </div> </td>
<td class = "tablebord">{{ item.lastipaddr }} </td>
</tr>
{% endfor %}
One solution that occurs to me:
In HTML:
Change method in form to POST.
Add CSRF Token to form.
Add hidden input with nodeid for parsing in view.
Pre-fill input with current comment.
<!-- Comment Cell -->
<td class = "tablebord">
<div contenteditable>
<form action="" method="post"> {% csrf_token %}
<input type="text" name="comment" value={{ item.comment }} />
<input type="hidden" value={{ item.nodeid }} name="nodeid" />
<input type="submit" value="edit" />
</form>
</div>
</td>
In views.py:
Import decorator for CSRF Token and Node model
Decorate view with CSRF Protect.
Check if form is submitted.
If so, get node and change comment.
Render template.
# decorator
from django.views.decorators.csrf import csrf_protect
from app.Node.models import Node
# view to handle table
#csrf_protect
def fruits(request):
nodes = Nodes.objects.all()
# user is posting: get edited node, change comment, and save
if request.POST:
nodeid = request.POST.get('nodeid')
edited_node = nodes.get(nodeid=nodeid)
edited_node.comment = request.POST.get('comment')
edited_node.save()
# render template with nodes
return render(request, 'fruits.html', {'nodes':nodes})
Hope this answers your problem.
Im new to Django and I am trying to create a form that contains a table of drop downs. This is for generating a script based on user selections in these drop downs when submit is clicked.
The problem is the following form template is creating duplicate form element ids
How do I create unique ids in the form template even though the drop downs are going to be repeated.
The following is the code of the drop down.
<html>
<table border="1">
<form action="/PrintTestScript/" method="post">
{% csrf_token %}
<tr>
<th>Action</th>
<th>Endpoint</th>
<th>Status</th>
<th>Box Type</th>
</tr>
{% for i in 0123456789|make_list %}
<tr>
<td>
{{form.action}}
</td>
<td>
{{form.series}}
</td>
<td>
{{form.epstatus}}
</td>
<td>
{{form.boxtype}}
</tr>
{% endfor %}
<tr>
<td>
<input type="submit" value="Submit" />
</td>
</tr>
</form>
</table>
</html>
The following is the form class definition.
class TestForm(ModelForm):
action = forms.ModelChoiceField(queryset=actions.objects.all(), empty_label="")
series = forms.ModelChoiceField(queryset=endpoints.objects.all(), empty_label="")
epstatus = forms.ModelChoiceField(queryset=status.objects.all(), empty_label="")
boxtype = forms.ModelChoiceField(queryset=boxtype.objects.all())
class Meta:
model = endpoints
exclude = ('end_point_alias', 'dial_num', 'ip_address')
This is where the view is getting created
def getvals(request):
form = TestForm()
return render_to_response('main.html', {'form':form}, context_instance=RequestContext(request))
Thanks for your help.
You need to put the <form> tag within the for loop, so that you are actually creating 10 different forms instead of 10 copies of the same form elements. But you still have the problem that you would need 10 separate submit buttons. If you're actually looking for a list of forms, check out the Django FormSet documentation.