Django Template not displaying model data, showing blank page
...Have a look at it:
models.py
class appointment(models.Model):
patient_name1= models.ForeignKey('identity')
appoint_date= models.DateTimeField('Appoinment time and date')
patient_info= models.TextField()
fees= models.CharField('Fees',max_length=100,blank=True)
class Meta:
verbose_name = 'Appointment Detail'
verbose_name_plural = 'Appoinment Details'
ordering = ['appoint_date']
def __str__(self):
return '%s (%s)' % (self. patient_name1, self.appoint_date)
views.py
from django.shortcuts import render
from .models import identity, appointment
def index(request):
return render(request, 'appoint/index.html')
def appointment_list(request):
Appointments = appointment.objects.all()
context = {'Appointments': Appointments}
return render(request, 'appoint/appointment_list.html', context)
appointment_list.html
<p>{{Appointments.patient_name1}}</p>
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^appointment_list/$', views.appointment_list, name='appointment_list'),
url(r'^aboutme/$', views.aboutme, name='about_us'),
url(r'^contact/$', views.contact, name='contact_us'),
url(r'^apply_appoint/$', views.apply_appoint, name='apply_appoint'),
]
please help me i am new to Django 1.9
you need to iterate over the queryset and then access object's attribute:
<p>
{% for appointment in Appointments %}
{{ appointment.patient_name1 }}
{% endfor %}
</p>
Appointments is a queryset which is a list of instances of Appointment class.
and you need to name your classes with Capital letter btw. Normally objects are in lowercase and class names begin with Capital letter.
Appointments is a list of model objects you need to loop over them in template
like this:
<p>
{% for object in Appointments %}
{{ object.patient_name1 }} , {{ object.appoint_date }}
{% endfor %}
</p>
Related
In this program i have these two functions in my views.py:
def home(request):
p=product.objects.all()
return render(request,'home.html',{'p':p})
def foods(request):
p=product.objects.all()
return render(request,'foods.html',{'p':p})
They both have access to the same data from database i mean if i want to post some json with django restframework then foods and home will have the same data because they have the same html:
<div class="grid">
{% for i in p%}
<div class='card'>
<img src="{{i.image}}"></img>
<p id="id">{{i.description}}</p>
<a href="{{i.buy}}" target='_blank' rel='noopener noreferrer'>
<button><span class="price"> ${{i.price}}</span> buy</button>
</a>
</div>
{%endfor%}
</div>
it is good for me to have just one html for multiple pages and then access to different data from database but if i add some json both of them will contain the same data(for some reason data of foods is empty but it will generate the same number of products based on json like home)
I want to know how can you have same html for multiple categories or pages and then add specific or different data from database to them?
More details:
models.py:
from django.db import models
# Create your models here.
class product(models.Model):
image=models.CharField(max_length=500)
description=models.CharField(max_length=500)
price=models.CharField(max_length=50)
buy=models.CharField(max_length=100)
serializers.py:
from rest_framework import serializers
from .models import product
class productSerializer(serializers.ModelSerializer):
class Meta:
model= product
fields="__all__"
views.py:
from django.shortcuts import render
from .models import *
from rest_framework import viewsets,status
from .serializers import productSerializer
from rest_framework.parsers import JSONParser
from django.http import HttpResponse,JsonResponse
from rest_framework.response import Response
from rest_framework.decorators import action
class productviewset(viewsets.ModelViewSet):
queryset=product.objects.all()
serializer_class = productSerializer
def create(self, request):
serialized = productSerializer(data=request.data, many=True)
if serialized.is_valid():
serialized.save()
return Response(serialized.data, status=status.HTTP_201_CREATED)
return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
#action (detail=False , methods=['post'])
def delete(self,request):
product.objects.all().delete()
return Response('success')
def home(request):
p=product.objects.all()
return render(request,'home.html',{'p':p})
def foods(request):
p=product.objects.all()
return render(request,'foods.html',{'p':p})
If i have 20 categories with 20 different pages i will never create 20 different databases if there is a way for those categories to access specifically from the same database.
If I understand the question correctly and you will have a certain amount of goods divided into 20 categories, then I somehow used this
You need to create a separate model for the categories, and in the product model add a foreign key to the category
models.py
class Category(models.Model):
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
def get_absolute_url(self):
return reverse('shop:product_list_by_category',
args=[self.slug])
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products')
available = models.BooleanField(default=True)
...
views.py
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category=category)
return render(request,
'shop/product/list.html',
{'category': category,
'categories': categories,
'products': products})
urls.py
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<category_slug>', views.product_list, name='product_list_by_category'),
]
html
{% block content %}
<div id="main" class="product-list">
<h1>{% if category %}{{ category.name }}{% else %}Products{% endif %}</h1>
{% for product in products %}
<div class="item">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
</div>
{% endfor %}
</div>
{% endblock %}
I've followed the tutorial here to implement a basic search function: https://learndjango.com/tutorials/django-search-tutorial
I'd like to extend that tutorial by making the search function visible on the results page, allowing for repeated search. However, when I do this I can't get the search form to show up on the search results page. The search button shows up, but not the field to provide input.
Relevant code:
home.html:
<div name="searchform">
<form action="{% url 'search_results' %}" method="get">
{{ form }}
<input type="submit" value="Search">
</form>
</div>
{% block content %}
{% endblock %}
search_results.html:
{% extends home.html}
{% block content %}
<h1>Search Results</h1>
<ul>
{% for city in object_list %}
<li>
{{ city.name }}, {{ city.state }}
</li>
{% endfor %}
</ul>
{% endblock %}
Views.py:
from django.db.models import Q
from django.views.generic import TemplateView, ListView, FormView
from .models import City
class HomePageView(FormView):
template_name = 'home.html'
form_class = SearchForm
class SearchResultsView(ListView):
model = City
template_name = 'search_results.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = City.objects.filter(
Q(name__icontains=query) | Q(state__icontains=query)
)
return object_list
urls.py:
from django.urls import path
from .views import HomePageView, SearchResultsView
urlpatterns = [
path('search/', SearchResultsView.as_view(), name='search_results'),
path('', HomePageView.as_view(), name='home'),
]
forms.py:
from django import forms
class SearchForm(forms.Form):
q = forms.CharField(label='', max_length=50,
widget=forms.TextInput(attrs={'placeholder': 'Search Here'})
)
Any advice on how I might troubleshoot this sort of issue (or if I'm blatantly doing something un-django-y) would be greatly appreciated.
You're using ListView which is a Generic display view.
You need to use get method, then you can pass the form to make the search again and stay on the same page.
class SearchResultsView(View):
template_name = 'search_results.html'
form_class = SearchForm
def get(self, request):
form = self.form_class()
query = self.request.GET.get('q')
context = {}
context['form'] = form
context['cities'] = City.objects.filter(
Q(name__icontains=query) | Q(state__icontains=query)
)
return render(self.request, self.template_name, context)
You can achieve the same result with ListView but is better if you use other based view class.
You can check the doc. here
class HomePageView(FormView):
template_name = 'home.html'
form_class = SearchForm # This line!
Remember to also apply the form_class attribute to SearchResultsView, otherwise, no forms will be interpreted. The submit button only shows up because it's not a part of the rendered form.
i created methods within my model class to handle my redirects all work except for the one i created for a link in my list view(go_to_create method ) im using class based views
class Todo(models.Model):
name = models.CharField(max_length=100, default='unamedTodo')
description = models.CharField(max_length=200)
Todo_date = models.DateTimeField('Todo Date')
pub_date = models.DateTimeField('Date Published')
def get_absolute_url(self):
return reverse('ToDo:detail', kwargs={'id': self.id})
def get_back_home(self):
return reverse('ToDo:todos', kwargs={})
def go_to_update(self):
return reverse('ToDo:update', kwargs={'id': self.id})
def go_to_create(self):
return reverse('ToDo:create', kwargs={})
class TodoCreateView(CreateView):
template_name = 'ToDo/todo_create.html'
form_class = TodoForm
queryset = Todo.objects.all()
from django.urls import path
from .views import (
TodoListView,
TodoDetailView,
TodoCreateView,
TodoUpdateView,
TodoDeleteView,
)
app_name = "ToDo"
urlpatterns = [
path('Todos/', TodoListView.as_view(), name='todos'),
path('Todos/<int:id>/', TodoDetailView.as_view(), name='detail'),
path('Todos/create/', TodoCreateView.as_view(), name='create'),
path('Todos/<int:id>/update/', TodoUpdateView.as_view(), name='update'),
path('Todos/<int:id>/delete/', TodoDeleteView.as_view(), name='delete')
]
<h1>ToDo's</h1>
<ul>
{% for object in object_list %}
<li>
<p>
{{ object.id }} -
{{ object.name }}
</p>
</li>
{% endfor %}
<p>Create new Todo here</p>
</ul>
the link calling the go_to_create method does not work i stay on the same page no error is generated
Instead of a method call directly on template,that will do the job.
{% url 'ToDo:create' %}
using Django 1.9
How to extract all objects from class table that linked with another class table by foreign key.
I mean not all objects from one id but i mean all objects from all ids in one page. when i'm trying it gives me just one result
For instance:
urls.py
from django.conf.urls import url
from . import views
app_name = 'music'
urlpatterns = [
# /music/
url(r"^$", views.HomeView.as_view(), name='home'),
# /music/123/
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='details'),
# /music/song/
url(r'^song/$', views.songView, name='songs'),
]
views.py
from django.views import generic
from .models import Album, Song
from django.shortcuts import render
class HomeView(generic.ListView):
template_name = 'music/index.html'
def get_queryset(self):
return Album.objects.all()
class DetailView(generic.DetailView):
model = Album
template_name = 'music/details.html'
# Get all songs from all album (extracting songs from all of the albums in one page)
def songView(request):
for albums in Album.objects.all():
all_album = Album.objects.get(id=albums.id)
all_song = all_album.song_set.all()
return render(request, 'music/song.html', {'all_song': all_song})
songs.html
{% extends 'music/base.html' %}
{% block body %}
{% for song in all_song %}
<h2>{{ song }}</h2>
{% endfor %}
{% endblock %}
Another simple way to get the values in template is:
def songView(request):
album = Album.objects.all()
return render(request, 'music/song.html', {'album': album})
and in your templates you can iterate this way
{% for item in album %}
<h2>{{ item.title }}</h2>
{% for song in item.song_set.all %}
<h2>{{ song.title }}</h2>
{% endfor %}
{% endfor %}
You're just iterating through the Album objects and on every interaction rewrite the all_song variable without storing it somewhere. The proper way would be:
def songView(request):
songs = []
for album in Album.objects.all():
songs_per_album = album.song_set.all()
songs.append(song_per_album)
return render(request, 'music/song.html', {'all_song': songs})
Also, take a look at serializers it can be useful when serializing nested structures.
I don't understand why you doing this?
def songView(request):
for albums in Album.objects.all():
all_album = Album.objects.get(id=albums.id)
all_song = all_album.song_set.all()
return render(request, 'music/song.html', {'all_song': all_song})
You get all albums and than again make request to db to get album, and you just get all songs of specific album, if you want to get all songs just get all of them
songs = Song.objects.all()
if you want to get songs where album fk not null you can do like this:
album_ids = list(Album.objest.values_list('id', flat=True))
songs = Song.objects.filter(album_id__in=album_ids)
or
songs = Song.objects.filter(album_isnull=False)
I'm new in Django. There is a html page (project_details) which should show the title and the tasks of the project, but shows only the title of the project, not the tasks. The tasks exists, the problem is the filter!!!
views.py The error is here
from .models import Project,Task
from django.views.generic import ListView, DetailView
class ProjectsList(ListView):
template_name = 'projects_list.html'
queryset= Project.objects.all()
class ProjectDetail(DetailView):
model = Project
template_name = 'projects_details.html'
def get_context_data(self, **kwargs):
context = super(ProjectDetail, self).get_context_data(**kwargs)
## the context is a list of the tasks of the Project##
##THIS IS THE ERROR##
context['tasks'] = Task.object.filter(list=Project) <---->HERE ((work with Task.object.all() ))
return context
models.py
class Project(models.Model):
title = models.CharField(max_length=30)
slug = AutoSlugField(populate_from='title', editable=False, always_update=True)
class Task(models.Model):
title = models.CharField(max_length=250)
list = models.ForeignKey(Project)
slug = AutoSlugField(populate_from='title', editable=False, always_update=True)
urls.py
from django.conf.urls import url
from .models import Project
from .views import ProjectsList, ProjectDetail
urlpatterns = [
url(r'^$', ProjectsList.as_view(), name='project_list'),
url(r'(?P<slug>[\w-]+)/$',ProjectDetail.as_view() , name='project_details'),]
projects_details.html
{% extends './base.html' %}
{% block content %}
<div>
<a href={{ object.get_absolute_url }}>
<h4> {{object.title}} </h4>
</a>
<ul>
{% for task in tasks %} <----> NO OUTPUT <li>
<li> {{task}}</li>
{% endfor %}
</ul>
</div>
{% endblock content %}
Sorry for my bad English.
Project is the model class, so doing (list=Project) doesn't make sense.
If you want to access the object in the detail view's get_context_data method, you can use self.object:
def get_context_data(self, **kwargs):
context = super(ProjectDetail, self).get_context_data(**kwargs)
context['tasks'] = Task.objects.filter(list=self.object)
return context
However, you don't actually have to override the get_context_data method at all. In your template, you can follow the relationship backwards from a project to get its tasks:
{% for task in object.task_set.all %}
<li>{{task}}</li>
{% endfor %}