I've got a django test-project going with a postgresql db with a table called customers.
Rendering all the customers in /customers/ is fine but I'm looking for a way to render a single customer like this: /customer/{{customer.id}}. Not really sure what I'm looking for, anyone that can guide me to the correct documentation or something?
Much appreciated.
List all customers and open given customer when clicking on the div:
<div class="container">
{% for customerz in custs_all %}
<br>
<div class="row shadow-sm d-flex w-1000 justify-content-between" onclick="location.href='/customers/{{customerz.id}}';" style="cursor: pointer;">
<div class="col-xl-4"><h5 class="mb-1">{{ customerz.name }}</h5></div>
<div class="col-xl-4">Contact person: {{ customerz.contactperson }}</div>
<div class="col-xl-4">Email: {{ customerz.email }}</div>
<div class="col-xl-4">Active: <span class="badge badge-light">{{ customerz.active }}</span></div>
</div>
{% endfor %}
</div>
So this is what I dont understand, what doc do I need to read to setup this to work?
onclick="location.href='/customers/{{customerz.id}}';"
I dont know what I'm looking for, so its hard to ask the right questions here.. Sorry
views.py
def customer_detail(request, pk):
customer = get_object_or_404(Customer, id=pk)
return render (request, template, {'customer': customer}
Here pk is primary key so you are getting a customer from your model Customer(or whatever you have named it).
urls.py
path('customer/<int:pk>/', views.customer_detail, name='customer-detail')
And in cutomer list template you can add link to add you customer detail template like cutomer detail
I think you are looking for this. You can pass an ID in the URL request and use it to get your desired object from the database.
urls.py
path('customer/<int:pk>/', views.customer_detail, name='customer-detail'),
views.py
def customer_detail(request, pk):
customer = Customers.objects.get(id=pk)
return render (request, 'customer.html', {'customer': customer})
customer.html
{% extends "base.html" %}
{% block content %}
<br>
<div class="container row">
<div class="col-xl-12"><h5 class="mb-1">{{ customer.name }}</h5></div>
<div class="col-xl-12">Active: <span class="badge badge-light">{{ customer.active }}</span><hr></div>
<div class="col-xl-12">Description: {{ customer.desc }}<hr></div>
<div class="col-xl-12">Contact person: {{ customer.contactperson }}</div>
<div class="col-xl-12">Email: {{ customer.email }}</div>
<div class="col-xl-12">Address: {{ customer.addr }}</div>
<div class="col-xl-12">Last updated: {{ customer.modified }}</div>
</div>
<br>
{% endblock %}
This is currently doing exactly what i want :)
The previous answer was correct, in action doe ; you could do something like this :
-- you could grab the customer id through request.form; if you use form within your table; i guess this is the best approach to do so.
-- than you can set something with (url_for), and give it a parameter as {{ customer.id}} , within your .html .
-- than handle the logic when returning this object.
You can check this project, go through it , you might find something similar to this :
[https://github.com/Nouamanezh909/BLog_repo][1]
Related
I was trying to pass a query set using context. But on template page the context is not working.
As I am implementing two queries in same view one query set is working fine but the other query is not passed well. Here is my view
# Create your views here.
def xray_result_view(request):
q=query_holding_together.objects.filter(which_user=request.user)
for x in q:
all_reports=xray_result.objects.get(which_query=x)
print(all_reports.sys_gen_result)
return render(request,'XRay/result.html',{'reports':all_reports})
when q is passed as template it is working as it should but it is not working for all reports. here is my template
{% extends "login/successful.html" %}
{% block middle_window %}
</div>
<div class="container adjust-ment">
<div class="row">
<div class="col-12">
Previous X-ray Results
</div>
</div>
<div class="row">
<div class="col-12">
Result
</div>
</div>
<div class="row">
<div class="col-12">
{% for y in reports.iterator %}
File Name:<br>
Date and Time of Upload:<br>
System Generated Result:{{ y.sys_gen_result }}<br>
Doctor's Comment on Result:{{ y.doctor_comment }}<br>
{% endfor %}
</div>
</div>
</div>
{%endblock middle_window %}
You are not passing a queryset in template, instead you are sending an object. Let me explain:
for x in q:
all_reports=xray_result.objects.get(which_query=x) #<-- Here
Here all_reports is a variable which has only a xray_result object. after the iteration is complete, all_reports will contain only the last object from q.
Instead, you can try like this:
def xray_result_view(request):
all_reports=xray_result.objects.get(which_query__which_user=request.user)
return render(request,'XRay/result.html',{'reports':all_reports})
And update the template:
{% for y in reports %}
File Name:<br>
Date and Time of Upload:<br>
System Generated Result:{{ y.sys_gen_result }}<br>
Doctor's Comment on Result:{{ y.doctor_comment }}<br>
{% endfor %}
Finally, consider using PascalCase when writing Class names(as per pep8 standard).
As #ruddra pointed out that there was problem with loop.
so for that I tried below workaround and it worked as a charm.
def xray_result_view(request):
q=query_holding_together.objects.filter(which_user=request.user)
all_reports=xray_result.objects.none()
for x in q:
all_reports = all_reports | xray_result.objects.filter(which_query=x)
for x in all_reports:
print(x.sys_gen_result)
return render(request,'XRay/result.html',{'reports':all_reports})
I'm building a Netflix like website for my Devops course. I made a Python list of dictionaries (Mockfilms) to define my films, and want to populate a database (Ratings) with reviews in preparation for sending data in the format :filmid: :userid: :rating: to a recommendation engine.
My index page is a list of film images with a link to a review form under each one. I want each review form to appear on a different url (/review/ID where ID is saved in mockfilms as oid). In order to do this I want to access mockfilms.oid, then pass it to the view function to make the url for the form. Once the form is complete I then want to add this ID to the Ratings database. Here is what I have so far:
Index:
{% extends "base.html" %}
{% block content %}
<h1>Hello, {{ current_user.username }}! Welcome to our extensive video library:</h1>
{% for film in mockfilms %}
{% set ID = film.oid %}
<div>
<a href = {{ film.video }}>
<img src = {{ film.image }} alt = "doh" style = "width:200px;height:200px;border:0;">
</a>
</div>
<div>
">Leave a review here!
{% endfor %}
{% endblock %}
Route:
#app.route('/review/<ID>', methods = ['GET', 'POST'])
#login_required
def review(ID):
form = ReviewForm()
if form.validate_on_submit():
review = Ratings(User_id = current_user.id, Score_given = form.score.data, Film_id = ID)
db.session.add(review)
db.session.commit()
flash('Thanks for your review')
return redirect(url_for('index'))
return render_template('review.html', title='Review Page', form=form)
The following error is what I get when I run it:
File "/home/jc/Desktop/Lokal/DevopsAssig/microblog/Kilfinnan/lib/python3.5/site-packages/werkzeug/routing.py", line 1768, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'review'. Did you forget to specify values ['ID']?
From this I assume that the issue is with the ID variable within this template. My searchings and learnings led me to believe that {% set %} in the index template would let me declare the ID variable and then use it in the dynamic.
Try this:
{% block content %}
<h1>
Hello, {{ current_user.username }}!
Welcome to our extensive video library:
</h1>
{% for film in mockfilms %}
<div>
<a href="{{ film.video }}">
<img src="{{ film.image }}" alt="doh" style="width:200px;height:200px;border:0;" />
</a>
</div>
<div>
<a href="{{ url_for('review', ID=film.oid) }}">
Leave a review here!
</a>
</div>
{% endfor %}
{% endblock %}
Ultimately your solution was quite close, but it is not necessary to use the Jinja set command when you need to pass the variable into url_for() function using the keyword for the parameter. You could still do it using {% set ID = film.oid %} but it would be a bit superfluous.
Try to provide key=value arguments into your url_for function.
Something like this
">Leave a review here!
Also Flask have a great documentation, Flask docs
So I am trying to get the latest post and I ran into a problem where it will not display the post
views.py
def latest_post(request):
latest = Post.objects.all().order_by('-id')[:1]
context = {'latestPost': latest}
return render(request, 'latest_post.html', context)
Note: I also tried it with this, latest = Post.objects.all()
There are entries in the database, I tested with the shell
from blog.models import Post
>>> Post.objects.all()
<QuerySet [<Post: test>, <Post: okay so>, <Post: okay-okay>]>
latest_post.html
{% for newest in latestPost %}
<section class="hero is-primary is-medium">
<div class="hero-body header">
<div class="container">
<div class="font">
<h1 class="title is-1">
<span id="blog_title">{{ newest.title }}</span>
</h1>
<h2 class="subtitle is-3 subup">
<span id="blog-subtitle">{{ newest.content|truncatechars:20|safe }}</span>
</h2>
<h2 class="subtitle is-5 dateup">
<span id="blogdate">{{ newest.timestamp }}</span><br><br>
Read More >>
</h2>
</div>
</div>
</div>
</section>
{% endfor %}
in my blog_index.html I have the following
{% extends "blog_base.html" %}
{% block blog_main %}
{% load staticfiles %}
{% include 'latest_post.html' %}
<p> other html here </p>
{% endblock %}
Latest_post.html displays when i use {% include 'latest_post.html' %} only if I don't use
{% for newest in latestPost %}
{% endfor %}
So i am sure there aren't any typos somewhere that prevents the latest_post.html from displaying in my index page.
my models.py
class Post(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
content = models.TextField()
draft = models.BooleanField(default=False)
publish = models.DateField(auto_now=False, auto_now_add=False)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return self.title
def blog_url(self):
return reverse("blogposts:blogdetail", kwargs={"slug": self.slug})
Additional Notes: python3, django 1.11, sqlite.
Also, No errors are displayed in the console. any help would be appreciated! thank you!!
Looks like you are passing context variable to latest_post.html directly:
return render(request, 'latest_post.html', context)
But there is no such context variable latestPost in blog_index.html.
What you need to do is add context to blog_index.html. Add this to index view also:
latest = Post.objects.all().order_by('-id')[:1]
context = {'latestPost': latest}
return render(request, 'blog_index.html', context)
Also you can use first to select first element in queryset.
In your previous code you are limiting it by using [:1] so it only returns one item. Then you are using a forloop again on one item. Not the best way to do things.
Are you trying to get only one item from the post? If yes, Forloop is not needed change your latest_post.html to
<section class="hero is-primary is-medium">
<div class="hero-body header">
<div class="container">
<div class="font">
<h1 class="title is-1">
<span id="blog_title">{{ latestPost.title }}</span>
</h1>
<h2 class="subtitle is-3 subup">
<span id="blog-subtitle">{{ latestPost.content|truncatechars:20|safe }}</span>
</h2>
<h2 class="subtitle is-5 dateup">
<span id="blogdate">{{ latestPost.timestamp }}</span><br><br>
Read More >>
</h2>
</div>
</div>
</div>
</section>
You don't even need to use the [:1] in your views. There are better ways to do this
I also stuck in the same problem and I was damn confirmed that I was doing any silly mistakes.
Unfortunately, I found one. So,
Try this:
context = {'latest': latest}
Instead of:
context = {'latestPost': latest}
I hope it works.
I'm making a simple blog for myself in Django, but having a strange issue. I have a simple model as shown below:
Entry:
- title
- content
This is the template I'm currently using:
{% for entry in context.entries %}
<div class="row">
<div class="col-xl-2 col-lg-2 col-md-2 hidden-sm hidden-xs"></div>
<div class="col-xl-8 col-lg-8 col-md-8 col-sm-12 col-xs-12">
<div class="entry">
<div class="header">
<table>
<tr>
<td class="title"><h2>{{ entry|title }}</h2></td>
<td class="datetime">01.01.2016 00:00:00</td>
</tr>
</table>
</div>
<div class="content">
{{ entry|content }}
</div>
<div class="footer">
#some
#tag
#right
#here
</div>
</div>
<div class="col-xl-2 col-lg-2 col-md-2 hidden-sm hidden-xs"></div>
</div>
</div>
{% endfor %}
However, I'm getting TemplateSyntaxError on the {{ entry|content }} line, which is strange.
views.py file:
import json, termcolor
from django.shortcuts import render
from django.http import HttpResponse
from .models import *
# Create your views here.
def index(request, page="1"):
page = int(page)
context = {
"title": "Erdin's Blog",
"entries": []
}
entries = Entry.objects.all()
r_entries = entries[::-1]
del entries
interest = [page*10-10, page*10]
context["entries"].extend(r_entries[interest[0]:interest[1]])
print(termcolor.colored(context["entries"][0].content, "green"))
return render(request, "home.elms.html", context)
Further Investigation
I already have a single entry on database. I also checked if it's queried correctly into database with sqliteman. Assuming I named this single entry as entry variable, I called entry.id, entry.title and entry.content and printed out to terminal, that was successful. There's no problem on database.
Environment
python3
Django 1.8.7
A Complete Edit
I currently realized the problem was completely different. I called {% for entry in context.entries %} but I already called context into template, so the engine was looking for a context key inside context dictionary.
The | syntax is for template filters. To get the model values in the template there is a dot notation:
{{ entry.title }}
{{ entry.content }}
Note that the reason why {{ entry|title }} did not throw any errors is that there is a built-in title template filter. But there is no content template filter - this is why you see the error on the line containing {{ entry|content }}.
Since I solved my own problem, I'm writing here for the sake of other users having same problem.
Since I returned a render in views.py as below:
render(request, "home.elms.html", context)
The template should call for dictionary inside the context as:
{% for entry in entries %}
not:
{% for entry in context.entries %}
I'm having trouble wiring my checkboxes together with the template to make a good user experience. I'm sending my form to the view which contains the following MyType which is described as:
models
class A(models.Model):
MyType = models.ManyToManyField(P)
forms
MyType = forms.ModelMultipleChoiceField(queryset=P.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)
and the view is being sent as:
return render(request, "static/about.html", {'form': form})
and in the template, I have the following kind of structure
<li class="option table">
<div class="cell" id="center">
<div class="option-text">Option 1</div>
</div>
<div class="cell" id="right">
<div class="option-checkbox">
<div class="check"></div>
<input id="myid1" name="myname1" value="1" type="checkbox">
</div>
</div>
Now I can use answer: On a django form, how do I loop through individual options per field? to loop through, but this only gives the description. How do I recreate the actual HTML that deals with the options in the smartest way?
I've tried the shell to look at the objects, but I really don't see what I should be pulling in. i.e. in the template to recreate. What fields of each option should I pull in? or how do I get at the right info to build up my HTML such that the saving aspect of the form will work.
In a template I cannot do:
{% for field in form["MySmoking"] %}
{% endfor %}
so how could I modify the following:
{% for option in form.MyType.field.choices.queryset %}
{{ option.image }}
{{ option.title }}
{{ option.description }}
{% endfor %}
so, how would I spit out the HTML that builds the checkbox.
Thanks.