Not able to display content on webpage using flask - python

Need some help, not getting the content from the database not sure why this is happening
using python flask,sqlalchemy with a small sqlite database
I need to see the content from the database displayed on the web page.
At the moment I see only the Home link which is static in the template file.
app.py contains a part of this
#app.route('/page/<int:page_id>')
def view_page(page_id):
page = db.session.query(Pages).filter_by(id=page_id).first()
return render_template('page.html', id=page.id, title=page.title.decode(),
content=page.content.decode())
page.html (this is the template)
{% extends "master.html" %}
{% block content %}
<!DOCTYPE html>
{% for page in pages %}
<h3>{{ page.title.decode() |truncate(150)}}
</h3></a>
<p>{{ page.content.decode() |safe | truncate(350) }}</p>
{% endfor %}
Home
{% endblock %}
</html>

You have to send model with your return template.
#app.route('/page/<int:page_id>')
def view_page(page_id):
pages = Pages.query.all()
return render_template('page.html', pages=pages)

Related

How to send object from detail view to another view in Django?

I have a detail view that uses a Quiz object to display data stored in that object, like title and author. I want to have a button that links to a new page that displays different data from the same object. I don't know how to pass this data/object.
I can render the view and pass it the context of a specific quiz using an id but I want the id to change to be the id of the object from the initial page.
#assessement view
def assessment(request):
context = {
'quiz':Quiz.objects.get(id=1),
}
return render(request, 'quiz_app/assessment.html', context)
#detailview template for quiz
{% extends "quiz_app/base.html" %}
{% block content %}
<article class="quiz-detail">
<h1>{{ object.title }}</h1>
<h2>{{ object.question_amount }} Questions</h2>
<a class="btn" href="{% url 'quiz-assessment' %}">Start Quiz</a>
</article>
{% endblock content %}
#assessment template
{% extends "quiz_app/base.html" %}
{% block content %}
<h2>Assessment</h2>
<h2>Title is {{ quiz.title }}</h2>
{% endblock content %}
Then you should make another view for url quiz-assessment and pass the quiz pk as you did above in your assessment view.
def quiz_assessment(request,pk):
quiz = Quiz.objects.get (pk=pk)
return render (request,'assessment_template', {'quiz':quiz}
And in your url,pass the quiz id like this:
path ('<int:pk>/quiz/assessment /',views.quiz_assessment,name='quiz_assessment')
And in your template you can give url like this:
< a class="btn" href="{% url 'quiz_assessment' object.pk %}>
As suggested in the comments by #Robin Zigmond, you can do like this.
#assessement view
def assessment(request, qid):
context = {
'quiz':Quiz.objects.get(id=qid),
}
return render(request, 'quiz_app/assessment.html', context)
In the HTML file
#detailview template for quiz
{% extends "quiz_app/base.html" %}
{% block content %}
<article class="quiz-detail">
<h1>{{ object.title }}</h1>
<h2>{{ object.question_amount }} Questions</h2>
<a class="btn" href="{% url 'quiz-assessment' qid=object.id %}">Start Quiz</a>
</article>
{% endblock content %}
and in your urls.py change as:
path('quiz_asswssment/?P<int:qid>/', views.assessment, name="quiz_assessment")
Besides, what SammyJ has suggested, You can use the django sessions library or the django cache framework. You can temporarily store the information you need for the next view and access it whenever you want to.
In what Sammy J had suggested, you will always to have make sure that the queryset is passed in the context, otherwise it will not be rendered.
def assesment(self, request, id):
q = Quiz.objects.get(pk=id)
request.session["someData"] = q.name
request.session["qAmount] = q.amount
In your template file
<p>The title is : {{request.session.title}} and the amount is {{request.session.qamount}}
Note: Django sessions do not allow you to set a queryset as a session record, for that, you can use Django Cache framework.
Example
from django.core.cache import cache
cache.set('quiz', q)
getting cache -> cache.get('quiz')
Sessions framework docs : https://docs.djangoproject.com/en/2.2/topics/http/sessions/
Cache framework docs: https://docs.djangoproject.com/en/2.2/topics/cache/

Flask required form on home page

I am looking for some kind of example with flask using a required form on the home page of my site that requires the user to select an option before being allowed onto the rest of the site. The form is used for selecting a collection out of my mongo db database. I need to know what collection the user wants to use before going anywhere else on the site. Once this done I need to make sure I can use this information on my other route and views on my site.
What you want is to implement a login infrastructure.
using flask, you have a base template, where every other template is extending, what you can do is something like the following:
base.html:
{% if current_user.is_authenticated %}
<content>
{% block content %}
{% endblock %}
</content>
{% else %}
<login-form>
{% block content %}
{% endblock %}
</login-form>
{% endif %}
using this code, the content is shown only and only if the user is authenticated. in login-form HTML you should have a form to ask the credentials needed to authenticate the user and then allow them access to rest of the site.
in other template files, you continue to use the same practice:
dashboard.html:
{% extends 'base.html' %}
{% block content %}
<YOUR HTML CONTENT>
{% endblock %}
the content of dashboard.html is only shown to the user, if they are logged in(current_user.is_authenticated = True)
this is because dashboard.html is shown inside the content block of base.html witch is only shown or rendered if that condition is met.
you can use anything else instead of is_authenticated like the collection being selected or anything like that. the procedure to do it is the same.

Django- understanding how information is displayed on webpage

I have recently taken over the development of a Django/ Python project, and am looking into fixing a particular bug within the system as it currently stands.
There is a database of projects with quite a large amount of information about each project stored. On one of the webpages, there is a button, which when clicked will add a new form to the page- the form allows the user to enter some details about a new object for the given project. If there are existing objects for that project within the database, a 'table' will be displayed with a form on each row for each of the existing objects, and the user can manually update the fields in the form to update the information about each of the objects in the database. They can also add a new 'row' to the 'table' to create a new object to add to that project.
This page is displayed by the view:
def current_ccis(request, budget_id):
"""
View the CCIs for the current budget
"""
budget = Budget.objects.select_related('project').get(id=budget_id)
project = budget.project
ccis = CciItem.objects.select_related('budget', 'budget__project', 'project_room', 'project_room__room').filter(budget_id=budget_id).order_by('project_room__order', 'created')
formset = CciItemFormset(queryset=ccis.exclude(name=None), form_kwargs={'project':project})
context = {
'ccis': ccis,
'project': project,
'budget': budget,
'formset': formset,
'widths': ['60px', '120px', '220px', '120px', '60px', '60px', '60px', '280px', '280px'],
}
return render(request, 'costing/ccis_current.html', context)
The first cell in each form of the formset for each object displays the 'type' of object that it is, and every other cell displays/ stores other information relevant to the object itself.
On another one of the webpages, there is then a report displayed about a given project which includes information based on what the user input into the forms on the page displayed by the view current_ccis(request, budget_id)
This page is displayed by the view:
def report_ccis(request, project_id):
""" CCI items styled for pdf """
project = Project.objects.get(id=project_id)
budget = get_current_budget(project_id)
cci_total_exc = budget.cci_total_exc_vat_final
cci_grouped_items = budget.cci_items.all().order_by('project_room', 'name')
context = {
'project': project,
'cci_total_exc': cci_total_exc,
'cci_grouped_items': cci_grouped_items,
'webview': 1,
}
try: context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs
except ObjectDoesNotExist: pass
if request.GET.get('stage') == 'pd':
""" Render post deposit homepage """
context['html'] = render_to_string('costing/report2_ccis.html', context)
context['active_tab'] = '4'
return render(request, 'costing/reports_post_deposit.html', context)
else:
""" Render pre deposit homepage """
context['html'] = render_to_string('costing/report_ccis.html', context)
context['active_tab'] = '5'
return render(request, 'costing/reports_pre_deposit.html', context)
and the report currently displays the information in the format:
Title
Project ID
Object
detail
detail
Object
detail
i.e. a list of Objects belonging to the project, and underneath 'Object title' a list of details belonging to that object.
The issue that I'm having here, is that for some projects, the 'Object' names are all displayed with their 'details' listed beneath each 'Object', but for others, the details are not listed under their respective 'Objects', but rather all listed under one 'Object', which is titled "None"...
What I don't understand, is why there is this inconsistency- why is that for some projects, the 'Object' names are shown on the report, with all of the 'details' listed under their respective 'Objects', but for other projects, all of the 'details' are listed under the Object 'None'...?
Anyone have any suggestions why this is?
Edit
The reports are displayed in the HTML files with:
(post deposit):
{% block tabs %}
{% with 'Payment schedule,Agreed variations,Variations not yet finalised,Client choice items,Overview'|listify as tabs %}
{% for tab_name in tabs %}
{% with forloop.counter as tab %}
{% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report2_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a>
{% endwith %}
{% endfor %}
{% endwith %}
{% endblock tabs %}
(pre deposit):
{% block tabs %}
{% with 'Overview, Construction budget, Schedule of works, Client choice items'|listify as tabs %}
{% for tab_name in tabs %}
{% with forloop.counter as tab %}
{% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a>
{% endwith %}
{% endfor %}
{% endwith %}
{% endblock tabs %}
Edit
The files where this HTML comes from both extend from the same HTML file (reports_tabbed.html), which has the following HTML:
{% extends "base.html" %}
{% load staticfiles utilities %}
{% block head_extras %}
<link rel="stylesheet" type="text/css" href="{% static "moon/scss/pdf-reports.css" %}">
{% endblock head_extras %}
{% block page_options %}
{% if request.user.first_name in 'Becky,Duncan'|listify and project.deposit_received %}
Make quick PDF
{% endif %}
{% endblock page_options %}
{% block content %}
<div class="tabbed m-r-lg text-sm">
<div class="navbar tabbed text-sm">
{% block tabs %}
{% endblock tabs %}
</div>
<div class="tabbed-section border {% block tabbed_class %}page{% endblock tabbed_class %}">
{{html}}
</div>
</div>
{% endblock content %}
{% block content_scripts %}
{% endblock content_scripts %}

What is a good way to get the dynamic title of a page in Django?

I'm trying to customize a share on Twitter button and I'm using to this to share:
http://twitter.com/intent/tweet?status=[TITLE]+[URL]
I'm able to get the URL with {{ request.get_host }} and {{ request.path }}, but I can't seem to get the title working. Are there any request objects I can use to get the title of my current page title? Thanks.
The easiest way to do this is:
Insert the following code in your base.html
#base.html
{% block title %} {% endblock %}
and following in your index or any Html file with your title
#index.html
{% extends 'base.html'%}
{% block title %} My Page Title {% endblock %}
Place your context object key in double paranthesis.
Lets take am making a dynamic teacher's page in a school management system
#urls.py
path("teacher/<str:pk>/",views.teacher,name="teacher"),
The vew
#view
def teacher(request,pk):
teacher = Teacher.objects.get(id=pk)
context= {"teacher":teacher}
return render(request,'main/teacher.html',context)
The template
<title>{{teacher.fname}} Page</title>

Using the pelican i18n subsites plugin with a static home page

I have a static homepage, but I'm also using the i18n subsites plugin. So for the homepage I have, in pelicanconf.py:
INDEX_SAVE_AS = 'blog/index.html'
INDEX_URL = 'blog'
and for the English version:
I18N_SUBSITES = {
'en': {
'OUTPUT_PATH': 'output/en/',
'INDEX_SAVE_AS': 'blog/index.html',
'INDEX_URL': 'blog',
}
}
(truncated unnecessary bits)
The problem lies with the translation link for the homepage. The translations macro has:
{% for translation in article.translations %}
{{ translation.lang | lookup_lang_name }}
So for the English-language homepage I could either set the url and output filename as:
<meta name="save_as" content="en/index.html">
<meta name="url" content="en/">
Which makes the translation link go to site.com/en/en/ (and works), or set them as:
<meta name="save_as" content="index.html">
<meta name="url" content="/">
Which conflicts with the standard-language homepage.
Another, related problem is that the index page (blog page) has no translation link to the English or back to the standard-language version whatsoever.
What can I do to solve this?
I was able to solve my problem with the following translations macro:
{% macro translations_for(article) %}
{% if extra_siteurls %}
{% for lang, url in extra_siteurls.items() %}
{% if article %}
{{ lang | lookup_lang_name }}
{% else %}
{{ lang | lookup_lang_name }}
{% endif %}
{% endfor %}
{% endif %}
{% endmacro %}
And by adding a permalink option the each article and page I can also translate the URL for said article or page (otherwise you could just use slug in the above macro).
Last but not least I also removed the url and save_as data from both homepages.
To fix the blog page, I added this to the index.html template:
{% block translation_links %}
{% if lang == 'nl' %}
English
{% else %}
Nederlands
{% endif %}
{% endblock %}
For the second part of your question, have a look at creating language buttons

Categories