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 %}
Related
I'm trying to create a frontend data entry page for an existing model. However, when clicking the link, I get an error:
crispy_forms.exceptions.CrispyError: |as_crispy_field got passed an invalid or inexistent field
Just to be clear, adding the data from Django Admin works with no issues at all.
Having looked through a number of answered questions here, one did highlight what I believe could be problem, but it was out of context and did not provide much of an explanation.
I am trying to create a frontend entry form for users that corresponds with a foreign key.
models.py
class NewHandoff(models.Model):
handoff_pk = models.AutoField(primary_key=True)
handoff_date = models.DateField(auto_now_add=True,verbose_name="Handoff Date")
shift1_pri = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Primary")
shift1_sec = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Secondary")
def __str__(self):
return f"{self.handoff_date}"
class Meta:
verbose_name_plural = 'Handoffs'
# New Handoff Form
class NewHandoffForm(forms.ModelForm):
class Meta:
model = NewHandoff
fields = ['shift1_pri','shift1_sec']
views.py
from django.shortcuts import redirect, render
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http.response import HttpResponse
from django.contrib import messages
from .models import AttentionForm, NewHandoffForm
# Handoff View Page
class NewHandoffView(LoginRequiredMixin,View):
def get(self, request):
greeting = {}
greeting['heading'] = "New Handoff"
greeting['pageview'] = "Handoff"
return render (request,'handoff/handoff-new.html')
def post(self, request):
if request.method == "POST":
if "add-new-handoff-button" in request.POST:
create_new_handoff_form = NewHandoffForm(request.POST)
create_new_handoff_form.save()
return redirect("/handoff/handoff-create")
handoff-new.html
{% extends 'partials/base.html' %}
{% load static %}
{% load humanize %}
{% load crispy_forms_tags %}
{% block extra_css %}
<link href="{% static 'libs/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet">
{% endblock %}
{% block contents %}
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<!-- New Form -->
<form method="POST">
{% csrf_token %}
<div class="row">
<div class="row-fluid pb-1">
<!-- Field 1 -->
<div class="mb-3">
{{ form.shift1_pri|as_crispy_field }}
</div>
<!-- End of Field 1 -->
</div>
</div>
<div class="d-flex flex-wrap gap-2">
<button type="submit" class="btn btn-primary waves-effect waves-light" name="add-new-handoff-button">Create New Handoff</button>
</div>
</form>
<!-- End of New Form -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_javascript %}
{% endblock %}
Someone mentioned in another post that forms should correlate with the declared form name {{ form.shift1_mod|as_crispy_field }} so it should actually be {{ create_new_handoff_form.shift1_mod|as_crispy_field }} but I have tried changing this and still get the same problem, plus, another model form works fine with just form despite the name of the form being attention_form.
Does anyone have any idea or can point me in the right direction? :)
You are not passing the form through the context in the template. As you are inheriting View, Add the following line in the get() and afterwards in the post() method appropriately:
form = NewHandoffForm()
# and then change return
return render(request,'handoff/handoff-new.html', {'form': form })
Also, you have a space after render in the get function. I hope this is a typo here, but not in your code.
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 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 checked multiple posts and solutions but can't make it happen.
I have a Python object returned within a view. I now want to use data from that dict to render it using Django template tags.
Somehow nothing shows up though...
View:
def render_Terminal(request, template="Terminal.html"):
account_information = AccountInformation.objects.all()
account_information_dict = {
'account_information': account_information
}
return render(request, template, (account_information_dict))
HTML
<div id="oneTwo" class="columnsOne">
{{ account_information.pk }}
</div>
Using just account_information within the tag, I get:
<QuerySet [<AccountInformation: AccountInformation object (30e61aec-0f6e-4fa0-8c1b-eb07f9347c1f)>]>
Where is the issue?
AccountInformation.objects.all() is a QuerySet with a all() filter. A QuerySet is iterable, and it executes its database query the first time you iterate over it. You can show the id for all items in your list using:
{% for item in account_information %}
<div id="some-id-{{ forloop.counter }}" class="some-class">
{{ item.pk }}
</div>
{% endfor %}
Do like this
def render_Terminal(request, template="Terminal.html"):
account_information = AccountInformation.objects.all()
account_information_dict = {
'account_information': [a for a in account_information]
}
return render(request, template, (account_information_dict))
and
<div id="oneTwo" class="columnsOne">
{{ account_information.0.pk }}
</div>
however you can only recover the first item that comes
a better solution might be
account_information = AccountInformation.objects.get(pk=`you id`)
return render(request, template, (account_information_dict))
and then
<div id="oneTwo" class="columnsOne">
{{ account_information.pk }}
</div>
Using just account_information within the tag, I get:
inside the html code you have to put the item in "for" if you take the integer value
{% for a in account_information %}
<div>
{{ a.pk }}
</div>
{% endfor %}
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.