Cannot render a list in template from django view - django

All my views are being rendered properly but when i try to render a list using iteration nothing is displayed on the page, without error.
the view:
from django.shortcuts import render
from haleys_chemist.models import anti_bacterials
from django.http import HttpResponse
from .table import anti_bacterials_Table
from django_tables2 import RequestConfig
from datetime import datetime
from django.http import HttpResponseRedirect
from .forms import notepadform
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView,ListView
class retriever(TemplateView):
template_name='index.html'
def expiry_days(self,request):
expired_drugs= anti_bacterials.objects.all()
args={'expired_drugs':expired_drugs}
return render (request, self.template_name,args)
template(index.html):
<h6><i>Drugs about to expire</i></h6>
{%for expired_drug in expired_drugs%}
<ul>
<li>{{expired_drug.Drug_name}}</li>
<li>{{expired_drug.expiry_date}}</li>
</ul>
{%endfor%}
</div>
model:
class anti_bacterials(models.Model):
Drug_id= models.IntegerField(primary_key=True);
Drug_name= models.CharField(max_length=50);
expiry_date= models.DateField();
Price_per_mg= models.DecimalField(decimal_places=2, max_digits=20)
i need to list the expired drugs on the left bar. i know i have queried for all objects on the view but still i should get a list of all the objects names and expiry dates.

You are not using the generic TemplateView properly.
The method expiry_days will never be called because the generic TemplateView doesn't know about it.
Simply you can use the method get_context_data to achieve what you want:
class retriever(TemplateView):
template_name='index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['expired_drugs']= anti_bacterials.objects.all()
return context
Read more about the generic TemplateView in Django's official documentation and here.

Related

How can i determine number object show per page when using ListView pagination in django?

please how can i determine number of objects/page show(not number of pages) in Django when using ListView Pagination.
that's my code in Views.py :
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Post
class PostList(ListView):
model=Post
context_object_name='all_post'
ordering=['-created_at']
thank you!
Just add paginate_by = <number of items in a page> to your view.
For example:
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Post
class PostList(ListView):
model=Post
context_object_name='all_post'
ordering=['-created_at']
paginate_by = 10 # 10 items in a page

How to use models variable as url?

In my models.py file i made a variable called hero_name. For instance, if the hero name is Bart, I want the url to be ./heroes/Bart
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<str:hero_name>/', views.heropage, name='heropage'),
]
views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Heroes
def index(request):
return render(request, 'heroes/index.html')
def heropage(request, hero_name):
get_object_or_404(Heroes, pk=hero_name)
return render(request, 'heroes/heropage.html')
models.py
from django.db import models
class Heroes(models.Model):
hero_name = models.CharField(max_length=200)
I think that you need to replace your implementation of get_object_or_404 with one that gets the object based on hero_name and not pk, since in your model, hero_name is not your primary key.
I hope this helps.
It's not clear exactly what you are asking. But you certainly need to use the relevant field to query the object, and pass the result to the template:
hero = get_object_or_404(Heroes, hero_name=hero_name)
return render(request, 'heroes/heropage.html', {"hero": hero})
Set the field you want to primary_key.
class Heroes(models.Model):
hero_name = models.CharField(primary_key=True)

can't display a value in the template

I am having trouble displaying the value on the html template from the mysql database.
my view:
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Min, Sum, Avg, Max
from .models import Gwtable
import datetime
def index(request):
max_value = Gwtable.objects.all().aggregate(Max('salesprice'))
return render(request, 'sql/index.html', context)
my html:
{{ max_value.values|floatformat:2 }}
Did you fill the context object like that context= { 'max_values':max_values} your html tag is correct one.

How to test a Django class-based view receives correct arguments?

I can't work out how to test that a Django class-based view receives the expected kwargs from a URL pattern.
If I have my urls.py:
from django.conf.urls import url
from myapp import views
urlpatterns = [
# ...
url(
regex=r"^people/(?P<pk>\d+)/$",
view=views.PersonDetailView.as_view(),
name='person_detail'
),
]
And my views.py:
from django.views.generic import DetailView
from myapp.models import Person
class PersonDetailView(DetailView):
model = Person
I can test that a request to the URL calls the correct view like this:
from django.test import TestCase
from django.urls import resolve
from myapp import views
from myapp.factories import PersonFactory
class UrlsTestCase(TestCase):
def test_person_detail_view(self):
PersonFactory(pk=3)
self.assertEqual(resolve('/people/3/').func.__name__,
views.PersonDetailView.__name__)
But I'd also like to test that a request to /people/3/ results in {'pk': '3'} being passed to PersonDetailView, and I can't work out where in a class-based view receives the kwargs in order to test it (by patching the receiving method, I guess).
Here's how I checked the id or pk on my views (I'm using Django1.11):
from menus.models import Item
from menus.views import ItemListView
from django.test import RequestFactory
from django.contrib.auth.models import User
person = User.objects.get(username='ryan')
factory = RequestFactory()
request = factory.get('/items/')
request.user = person
response = ItemListView.as_view()(request)
#prints the id or pk of the requesting user
response._request.user.pk
response._request.user.id

A weird Django error

This is my views.py:
# Create your views here.
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.db import models
from display.forms import CodeForm
from display.forms import CodeFormSet
from ExamPy.questions.models import QuestionBase
def codepost(request):
if request.method == 'POST':
form = CodeFormSet(request.POST)
if form.is_valid():
titles = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
title = form.cleaned_data['title']
if title in titles:
raise forms.ValidationError("Articles in a set must have distinct titles.")
titles.append(title)
return render_to_response('quesdisplay.html')
else:
form = CodeFormSet()
return render_to_response('quesdisplay.html', {'form':form})
Thus, when I click on submit button, it should show the quesdisplay.html without any form in it. But, it is taking me to some contact page which doesn't even exist.
Error:
The current URL, contact/, didn't match any of these.
I've tried all possible ways to debug this but its not possible as there is no trace of anything called "contact" in this.
Edit:
This is the warning I get:
/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py:101: UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.
warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.")
[10/Nov/2011 05:34:17] "
As seen in the comment before, using Requestcontext solve your problem.
Here is the documentation about csrf_token : https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-to-use-it
As we can read :
Use RequestContext, which always uses
'django.core.context_processors.csrf' (no matter what your
TEMPLATE_CONTEXT_PROCESSORS setting). If you are using generic views
or contrib apps, you are covered already, since these apps use
RequestContext throughout.
So here it seems we're not using a generic view, neither a contrib app.
So what we need it to pass the RequestContext because it's like that csrf protection works in Django.
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
c = {}
c.update(csrf(request))
# ... view code here
return render_to_response("a_template.html", c)
or
from django.views.generic.simple import direct_to_template
def app_view(request):
return direct_to_template(request, 'app_template.html', app_data_dictionary)
or
from django.shortcuts import render_to_response
from django.template import RequestContext
def app_view(request):
return render_to_response('app_template.html',
app_data_dictionary,
context_instance=RequestContext(request))
Also the documentation speaks about : extras/csrf_migration_helper.py script.
Seems to be helpful for your case :)
Hope it helps ;)