Django not passing context well - python

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})

Related

Unable to render Listblock inside StreamBlock in template Wagtail

I have StructBlock inside a Listblock, all of which sit insde a class BannerBlock as follows:
class BannerBlock(blocks.StreamBlock):
"""
Blocks for displaying individual banners
"""
banners = blocks.ListBlock(
blocks.StructBlock(
[
('image', ImageChooserBlock(required=True)),
('title', blocks.CharBlock(required=True, max_length=128)),
('description', blocks.CharBlock(required=True, max_length=1024)),
('link', blocks.URLBlock(required=False)),
]
)
)
class Meta:
template = "home/banner_block.html"
icon = "placeholder"
label = "Banners"
The template Banner_block is as follows:
{% load wagtailimages_tags %}
<!-- Banner -->
<div id="banner">
{% for banner in self.banners %}
<article data-position="bottom right">
<div class="inner">
{% image banner.image original as image %}
<img src="{{ image.url }}" alt="">
<div class="features">
<a href="{{ banner.link.url }}" class="c-accent alt no-bg">
<h2>{{ banner.title }}</h2>
<p>{{ banner.description }}</p>
</a>
</div>
</div>
</article>
{% endfor %}
</div>
Finally, I am trying to render each Banner (Listblock) as follows:
{% for block in page.banners_collection %}
{% include_block block %}
{% endfor %}
However, Each Listblock is rendered as plain text as list items.
How do I render each item correctly?
Thank you.
I'm assuming the banners_collection field on your page model is defined as:
banners_collection = StreamField(BannerBlock())
where you're specifying a StreamBlock to use at the top level of the StreamField, rather than the more basic setup of
some_stream = StreamField([
('first_block_type', some_block_definition),
('another_block_type', some_block_definition),
])
where you pass a list of blocks for StreamField to make a stream from. This means that when you access page.banners_collection, it will give you a single instance of a BannerBlock value. When you loop over this value with for block in page.banners_collection, you're actually getting back the ListBlock values in your stream, and rendering them individually with include_block - bypassing the template you set up for BannerBlock. Your ListBlock values don't have a template of their own, so they end up using the default rendering.
If you call include_block on the BannerBlock value as a whole:
{% include_block page.banners_collection %}
then it will use your template. However, there's a secondary problem - in the line
{% for banner in self.banners %}
self.banners is not valid, because a stream value behaves as a sequence, not a dictionary. You can't look up the banners children by name - you need to loop over the list of children finding the ones that are of type banners. (Except, in your case, you can skip that check because banners is the only available block type within the stream). The correct template code would look like:
<div id="banner">
{% for block in self %}
{# the 'block' object here has properties block_type (which is always 'banners' here) and value #}
{% for banner in block.value %}
{# banner is a StructBlock value, with image, title, description, link properties #}
<article data-position="bottom right">
<div class="inner">
{% image banner.image original as image %}
...
</div>
</article>
{% endfor %}
{% endfor %}
</div>
However, are you sure you need the ListBlock in addition to the StreamBlock? A StreamBlock is already a sequence of blocks, so a ListBlock inside a StreamBlock gives you a list of lists of banners. If you simplified the BannerBlock value to
class BannerBlock(blocks.StreamBlock):
"""
Blocks for displaying individual banners
"""
banner = blocks.StructBlock(
[
('image', ImageChooserBlock(required=True)),
('title', blocks.CharBlock(required=True, max_length=128)),
('description', blocks.CharBlock(required=True, max_length=1024)),
('link', blocks.URLBlock(required=False)),
]
)
class Meta:
template = "home/banner_block.html"
icon = "placeholder"
label = "Banners"
then BannerBlock as a whole would be a list of banners, and the template would become
<div id="banner">
{% for block in self %}
{# block.value is now a StructBlock value #}
<article data-position="bottom right">
<div class="inner">
{% image block.value.image original as image %}
...
</div>
</article>
{% endfor %}
</div>

Django, link to object in db

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]

I'm making a flask quiz web page and I'm trying to print the score to the user [duplicate]

This question already has answers here:
Flask view return error "View function did not return a response"
(3 answers)
Closed 3 years ago.
I am making a quiz with flask and I am trying to get the score for the user but every time I reload the page I get this error: 'TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.'
The quiz includes questions that is stored on a database using sqlalchemy. I have successfully queried the database to display the questions on my page
This is the code for the html which display the questions on the page
<h5 class="center-align">Answer the Questions</h5>
<form action="http://localhost:5000/info" method='POST'>
{% for computersystemsq in computersystemsq %}
{% for computersystemsm in computersystemsm %}
<div class="row">
<div class="col s12">
{{ computersystemsq.question }}
</div>
</div>
<div class="{{ computersystemsm.id }}"></div>
<div class="row">
<div class="col s6">
A: {{ computersystemsm.wrong_answer1 }}
</div>
<div class="col s6">
B: {{ computersystemsm.wrong_answer2 }}
</div>
</div>
<div class="row">
<div class="col s6">
C: {{ computersystemsm.answer }}
</div>
</div>
<div class="row">
<div class="input-field col s6">
{{ form.options( class= computersystemsm.id ) }}
<label for="attempted_answer">Select an Option:</label>
</div>
</div>
<button class="btn waves-effect waves-light" type="submit" id="{{ computersystemsm.id }}">mark</button>
<br>
</div>
{% endfor %}
{% endfor %}
</form>
This is the query made to get the computersystemsquestions and the computersystemsmultiplechoices from the table(two tables, computersystemsquestions stores the question and computersystemsmultiplechoices stores the answer, wrong_answer1, wrong_answer2)
#app.route("/computersystems", methods=['GET','POST'])
def computersystems():
form=QuizForm()
computersystemsq=ComputerSystemsQuestions.query.filter(ComputerSystemsQuestions.id).all()
computersystemsm=ComputerSystemsMultipleChoices.query.filter(ComputerSystemsMultipleChoices.id).all()
return render_template('computersystems.html',computersystemsq=computersystemsq,computersystemsm=computersystemsm, form=form)
this is the code which I'm using to store the request values and to get the score
#app.route("/info", methods=['GET','POST'])
def info():
value = request.args.get('value', 0, type=str)
computersystemsm=ComputerSystemsMultipleChoices.query.filter(ComputerSystemsMultipleChoices.id).all()
#if request.method == 'POST':
quizscore = 0
if computersystemsm[0].answer == value:
quizscore = quizscore + 1
return render_template('info.html', quizscore=quizscore,computersystemsm=computersystemsm)
I am expecting to get a score displayed to the user doing the question like so:
<p>you've scored {{quizscore }}</p>
With Flask you will need to account for all possible outcomes when designing a view (route). In your last code snippet, there are a few things to mention. Firstly, create some logic to handle the different methods that your view is supporting.
def info():
if (request.method == 'GET'):
pass
elif (request.method == 'POST'):
pass
http://flask.pocoo.org/docs/1.0/quickstart/#http-methods
You could use else statement instead of the elif but I prefer this way so that I can easily add support for a PUT method if necessary in the future.
Secondly, you need to return something for when your if statement equates to False.
I would suggest:
if computersystemsm[0].answer == value:
quizscore = quizscore + 1
return render_template('info.html', quizscore=quizscore,computersystemsm=computersystemsm)
else:
return abort(500)
This will return a generic internal server error if your logic does not equate to True. If you use this method, make sure you have imported abort
from flask import abort
http://flask.pocoo.org/docs/0.12/quickstart/#redirects-and-errors

How do I convert a string, represented as a list in MySQL database to a list in Django Template, so that I can iterate over it?

UPDATE:
Additional information:
Python version: 3.4
OS: Windows
Django: 1.11.18
MySQL 8
models.py
mailing_address = models.JSONField()
views.py
# while inserting data
data.locations = json.dumps(request.POST.getlist('locations'))
data.save()
# while retrieving data
my_requests_queryset = ListingModel.objects.filter(owner=request.user)
return render(request, 'home/home_dashboard_my_requests.html', {'my_requests_queryset': my_requests_queryset})
I have stored a list of mailing addresses in the MySQL database like:
['1212 Los Angeles, CA', 'Nariman Point, Mumbai, India']
I expect to print each element of the list in my HTML template. Unfortunately, each character is being printed.
Now, when I try to iterate over the list, in the Django template, I get each character instead of each list element.
I have tried the Django library, django-mysql to implement native JSONField.
Tried building a list in Django template, using in-built template filters, with, cycle, as list, amongst others.
<div class="container">
{% if my_requests_queryset and my_requests_queryset|length > 0 %}
{% for req in my_requests_queryset %}
<div class="row mb-1">
<div class="col-lg-2"></div>
<div class="col-lg-8">
<a href="#" class="card-link">
<div class="card text-center">
<div class="card-header">
{{ req.title|title|truncatechars:36 }}
</div>
<div class="card-body">
<h5 class="card-title">
{% for address in req.locations %}
{{ address }}
{% endfor %}
</h5>
</div>
</div>
</a>
</div>
</div>
{% endfor %}
{% endif %}
</div>
I expect to print each element in a list as:
1212 Los Angeles, CA
Nariman Point, Mumbai, India
The problem here is, I'm using json.dumps() to insert the data into the database, which gets converted in to String type.
Hence, I need to do json.loads() before I could neatly display the data.
So, to solve this error, I have directly inserted the values into the database, like
locations = request.POST.getlist('locations')
instead of
locations = json.dumps(request.POST.getlist('locations'))

Cannot Render Entries to Page

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 %}

Categories

Resources