Django html display from model - python

I need on my html page to display data from Profesor and Ucenik model: ime, prezime, jmbg.
{{profesor.ime}}
{{profesor.prezime}}
{{ucenik.ime}}
{{ucenik.prezime}}
{{ucenik.jmbg}}
my profile page id dynamic, need to display profesor data or if ucenik to display ucenik data
what i need to add on my views.py
models.py
class Profesor(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
ime = models.CharField(max_length=200, null=True)
prezime = models.CharField(max_length=200, null=True)
class Ucenik(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
ime = models.CharField(max_length=200, null=True)
prezime = models.CharField(max_length=200, null=True)
jmbg = models.IntegerField(null=True)
urls.py
path('profesor/', views.profesor, name='profesor'),
path('ucenik/', views.ucenik, name='ucenik'),
path('posetioc/', views.posetioc, name='posetioc'),
path('profil/<str:pk>/', views.profil, name='profil'), ]
views.py
def profesor(request):
return render(request, 'pocetna_profesor.html')
def ucenik(request):
return render(request, 'pocetna_ucenik.html')
def profil(request, pk):
return render(request, 'profil.html')
HTML:
{% extends 'base.html' %}
<title>profesor</title>
{% block content %}
<body>
{% include 'navbar.html' %}
<h1>Ime:</h1>
{{profesor.ime}}
</body>
{% endblock %}

You need to add a Professor and Ucenik instance to your view context.
context = {
'professor': Professor.objects.get(),
'ucenik': Ucenik.objects.get()
}
return render(request, context, 'url.html')

You can make your profile view dynamic by introducing an extra parameter which defines your role (i.e, Professor/Ucenik)
/profil/profesor/2/ for profesor
/profil/ucenik/1 for ucenik
from django.urls import path
urlpatterns=[
path('profil/<str:role>/<int:pk>/', views.profil, name='profil'),
]
# views.py
from .models import Profesor,Ucenik # import your model
def profil(request,role,pk):
context = {}
context['role'] = type
if type=="profesor":
context['person'] = Profesor.objects.get(id=pk)
else:
context['person'] = Ucenik.objects.get(id=pk)
return render(request, 'profil.html',context)
<!-- profil.html -->
{% extends 'base.html' %}
<title>{{role}}</title>
{% block content %}
<body>
{% include 'navbar.html' %}
<h1>Ime:</h1>
{{person.ime}}
</body>
{% endblock %}

Different Approach:
Assuming your User Model is having an id or any unique field.
You could use that id to be your profil id (i.e, url's <int:pk>).
so instead of profil/profesor/3, you can use profil/3 which must be definitely one of two categories(assuming profesor and ucenik are mutually exclusive).
So in order to do that import User model into views along with other models.
views.py
from django.shortcuts import render
from ..models import User # give correct path to user model
from .models import Profesor,Ucenik
def profil(request,pk):
context={}
person = User.objects.get(id=pk)
try :
person.profesor
# print(dir(person))
except Profesor.DoesNotExist:
context['person'] = Ucenik.objects.get(id=person.ucenik.id)
else:
context['person'] = Profesor.objects.get(id=person.profesor.id)
return render(request,"profil.html",context)
urls.py
from django.urls import path
from .views import profil
urlpatterns = [
path('profil/<int:pk>/',profil) # I have used int
]
I used person,neutral variable name instead of profesor or ucenik.
You can name it anything even profil
profil.html
{{person.id}}
{{person.ime}}
{{person.prezime}}
{% if role == "ucenik" %}
{{person.jmbg}}
{% else %}
<!-- profesor does not have jmbg -->
{% endif %}

Related

How to render many to many field data in Django template

I am able to render list of all courses and list of topics corresponding to the courses in different templates.
I need help to view list of all courses and when each course is clicked,a new page should show the list of associated topics
models.py
class Topic(models.Model):
topic_name = models.CharField(max_length=200, null=True)
topic_file = models.FileField(upload_to = "topic_file", blank=True, null=True)
def __str__(self):
return self.topic_name
class Course(models.Model):
course_name = models.CharField(max_length=200, null=True)
course_image = models.ImageField(upload_to="images", blank=True, null=True)
related_topic = models.ManyToManyField(Topic)
def __str__(self):
return self.course_name
Views.py
def view_course(request):
course_list = Course.objects.all()
context = {'course_list':course_list}
return render(request, 'upskill/view_course.html',context)
def course_topic(request,pk):
course_topic_list = Course.objects.get(id=pk)
var = course_topic_list.related_topic.all
context = {'var':var}
return render(request, 'upskill/course_topic.html',context)
Here is how you could get the related topics inside of a template.
{% for course in course_list %}
... data
{% for topic in course.related_topic.all %}
...data
{% endfor %}
{% endfor %}
If you don't want to do a query every single iteration of the {{course}} loop, I recommend you this in your views:
course_list = Course.objects.all().prefetch_related('related_topic')
And for a single object:
def course_topic(request,pk):
course = Course.objects.prefetch_related('related_topic').get(id=pk)
context = {'course ':course }
return render(request, 'upskill/course_topic.html',context)
And then in the template:
{{course.data...}}
{% for topic in course.related_topic.all %}
...data
{% endfor %}
To only have topics:
def topic_view(request, pk)
topics = Topic.objects.filter(course__pk=pk) #The reverse name of Course model.
# You can set a related name the "related_topic" field.
# Then access the above filter with that related name.
.... data
context = {
"topics":topics
}
return render(request, 'template.html', context)

How do i import single object from django to a html template

i am creating a website with django and i have 2 models in it,1:Gifi(contains .gif images) and 2:categorite! When i click one of the .gif images i want to be sent to another html template where that image shows and information about it.I have done some coding and when i click the image i get to the html page but the problem is that no data from django gets imported to that html page,except the id on the url.I know the problem is so simple but i am new to this and i dont know the code.
This is the models:
from django.db import models
class categorite(models.Model):
name = models.CharField(max_length=100)
id = models.AutoField(primary_key=True)
class Gifi(models.Model):
foto = models.ImageField(upload_to='website/static/')
emri = models.CharField(max_length=100)
Source = models.CharField(max_length=100)
Kodet = models.CharField(max_length=12)
categoryId = models.ForeignKey(categorite, on_delete=models.CASCADE)
id = models.AutoField(primary_key=True)
This is views.py:
from django.shortcuts import render,get_object_or_404
from .models import Gifi,categorite
# Create your views here.
def home(request):
return render(request, 'website/home.html')
def categories(request):
content = {
'view': categorite.objects.all()
}
return render(request, 'website/categories.html',content)
def PostaCode(request):
return render(request, 'website/PostaCode.html')
def Contact(request):
return render(request, 'website/Contact.html')
def category(request,id):
content = {
'view': Gifi.objects.filter(categoryId_id=id),
}
return render(request, 'website/category.html',content)
def code(request,id):
content = {
'view': get_object_or_404(Gifi,pk=id)
}
return render(request, 'website/code.html',content)
This is the template where i click the image:
{% for gifi in view %}
<a href="{% url 'code' gifi.id %}" class="gif">
<img src="/static/{{gifi.foto}}" id="foto" alt="" >
<p id="source">Source: {{gifi.Source}}</p>
<p id="permbatjaa">Coding: {{gifi.Kodet}}</p>
</a>
{% endfor %}
This is the template where i need to get to, and where information about image should be(code.html):
<img src="/static/{{gifi.foto}}" id="foto" alt="" >
<p>{{gifi.emri}}</p>
It is passed a few days so you might get an answer already but Django's view function and the template are so simple, and you could write:
The models.py:
from django.db import models
class Categorite(models.Model):
# id field is already exists models.Model not necessary
#id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
class Gifi(models.Model):
foto = models.ImageField(upload_to='website/static/')
emri = models.CharField(max_length=100)
source = models.CharField(max_length=100)
kodet = models.CharField(max_length=12)
category = models.ForeignKey(Categorite, on_delete=models.CASCADE, related_name='gifis')
And the views.py:
def category(request, id):
# For the foreign key fields _id field auto created also
objs = Gifi.objects.filter(category_id=id)
return render(request, 'website/category.html', {'gifis': objs})
def code(request, id):
obj = get_object_or_404(Gifi, pk=id)
return render(request, 'website/code.html', {'gifi': obj})
And the template website/category.html
{% for gifi in gifis %}
<a href="{% url 'code' gifi.id %}" class="gif">
<img src="/static/{{gifi.foto}}" id="foto" alt="" >
<p id="source">Source: {{gifi.source}}</p>
<p id="permbatjaa">Coding: {{gifi.kodet}}</p>
</a>
{% endfor %}
And the template website/code.html
<img src="/static/{{gifi.foto}}" id="foto" alt="" >
<p>{{gifi.emri}}</p>
To meet PEP 8 spec, under_score recommended for the variable names, and CamelCase is recommended for the class names.
If you are new to Django, I highly recommend the official tutorial page would help a lot.

Updating a Django Model from DetailView

I have a Django model that is receiving most of it's variable values from a form created by User 1 using CreateView. User 1 creates an object and selects most field values.
Once the object is created it is posted to a wall, another user (User 2) can access the object and add information for the final unfilled field. My question is, how do I allow for this functionality in the DetailView html form? In the code below, "basketball.salary2" is the previously empty field User 2 will be inputting and posting in the DetailView. All other values are already filled in and displaying in the HTML.
basketball_detail.html:
{% extends "base.html" %}
{% block title %}By: {{ basketball.creator }}{% endblock %}
{% block content %}
<h2>{{ basketball.creator }} has placed an opinion:</h2>
<p>{{ basketball.creator }} says that {{ basketball.player }} deserves
{{ basketball.salary1 }}
<p> Do you agree with {{ basketball.creator }}? </p>
<p>I believe {{ basketball.player }} deserves {{ basketball.salary2 }} <p>
{% endblock content %}
views.py:
from django.shortcuts import render
from django.views.generic import ListView, CreateView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Basketball
class BasketballListView(LoginRequiredMixin, ListView):
model = Basketball
class BasketballDetailView(DetailView):
model = Basketball
class BasketballCreateView(LoginRequiredMixin, CreateView):
model = Basketball
fields = [
'player',
'salary1',
'salary2',
]
def form_valid(self, form):
form.instance.creator =self.request.user
return super().form_valid(form)
models.py:
from django.db import models
from django.urls import reverse
from django.conf import settings
from django.utils.text import slugify
from autoslug import AutoSlugField
from model_utils.models import TimeStampedModel
from nba_api.stats.static import players
PLAYER_CHOICES = [(i['full_name'], i['full_name']) for i in players.get_active_players()]
class Basketball(TimeStampedModel):
player = models.CharField(max_length = 50, choices = PLAYER_CHOICES, default = None)
slug = AutoSlugField("Basketball Player", unique = True, populate_from ="player")
salary1 = models.DecimalField(decimal_places = 2, max_digits = 15)
salary2 = models.DecimalField(decimal_places = 2, max_digits = 15)
creator = models.ForeignKey(settings.AUTH_USER_MODEL,
null = True,
on_delete = models.SET_NULL
)
def get_absolute_url(self):
return reverse(
'basketball:detail', kwargs={'slug': self.slug}
)
I think for this case UpdateView will work instead of DetailView.
class BasketballUpdateView(UpdateView):
model = Basketball

Display List of objects from another Model Django

I am new to stackoverflow and I don't know how to properly paste Django code. Please bear with me.
Anyway, here's my problem:
"I want to display DormRoom.room_number in a template as a list (sample: Rooms: 401, 402, 403, 404, etc)."
enter image description here
Models.py >
class Dorm(models.Model):
dorm_name = models.CharField(max_length=50, help_text="Enter dorm name")
dorm_description = models.TextField(max_length=1000, help_text="Enter dorm description")
dorm_primary_picture = models.ImageField(help_text="Enter dorm primary pic")
dorm_room_count = models.IntegerField(help_text="Enter no. of rooms")
dorm_address = models.CharField(max_length=100,help_text="Enter dorm address")
dorm_caretaker = models.CharField(max_length=50,help_text="Enter caretaker name")
dorm_contact_no = models.CharField(max_length=50,help_text="Enter dorm contact number")
dorm_contact_email = models.EmailField(max_length=254,help_text="Enter dorm email")
dorm_date_added = models.DateTimeField(help_text="Enter Date Dorm was created")
dorm_availability = models.CharField(max_length=50, help_text="Is dorm available")
dorm_date_updated = models.DateTimeField(help_text="Enter Date Dorm information was updated")
dorm_house_rules = models.TextField(max_length=1000, help_text="Enter dorm house rules")
class Meta:
ordering = ["-dorm_name"]
def get_absolute_url(self):
return reverse('dorm-detail',args=[str(self.id)])
def __str__(self):
return self.dorm_name
class DormRoom(models.Model):
room_number = models.CharField(max_length=20, help_text="Enter room number")
room_maxusers = models.IntegerField(help_text="Enter maximum # of room users")
room_dorm = models.ForeignKey(Dorm, on_delete=models.CASCADE)
room_count = models.IntegerField(help_text="Enter # of rooms in this Dorm room")
def get_absolute_url(self):
return reverse('rooms-detail', args=[str(self.id)])
def __str__(self):
return self.room_number
class Meta:
ordering = ('room_number',)
URLs.py >
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('list/', views.DormsListView.as_view(), name='dorms'),
path('list/<int:pk>', views.DormsDetailView.as_view(), name='dorm-detail'),
path('rooms/', views.DormsRoomView.as_view(), name='rooms'),
path('rooms/<int:pk>', views.DormsRoomsDetailView.as_view(), name='rooms-detail'),
]
Views.py >
from django.shortcuts import render
from .models import Dorm, DormRoom
from django.views import generic
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
#login_required
def index(request):
num_dorms = Dorm.objects.all().count()
num_visits = request.session.get('num_visits',0)
request.session['num_visits'] = num_visits+1
return render(
request,
'index.html',
context = {'num_dorms':num_dorms,'num_visits': num_visits},
)
class DormsListView(LoginRequiredMixin, generic.ListView):
model = Dorm
paginate_by = 4
class DormsDetailView(LoginRequiredMixin, generic.DetailView):
model = Dorm
class DormsRoomView(LoginRequiredMixin, generic.ListView):
model = DormRoom
class DormsRoomsDetailView(LoginRequiredMixin, generic.DetailView):
model = DormRoom
Dorm_Detail.html >
{% extends "base_generic.html" %}
{% block content %}
<div class="padding-small"><img class="image-standard" src="{{ dorm.dorm_primary_picture.url }}"/></div>
<h1><b>{{ dorm.dorm_name }}</b></h1>
<h5>Address: {{ dorm.dorm_address }}</h5>
<h5>{{ dorm.dorm_description }}</h5>
<div><br/></div>
<div>Available Rooms: {{ dorm.dorm_room_count}}</div>
<div>Rooms: {{ dormroom.room_number }}</div>
<div><br/></div>
<h4><b>Contact Details</b></h4>
<div>Administrator: {{ dorm.dorm_caretaker }}</div>
<div>Phone Number: {{ dorm.dorm_contact_no }}</div>
<div>Email Address: {{ dorm.dorm_contact_email }}</div>
<div>Date Added: {{ dorm.dorm_date_added }}</div>
<div>Last Updated: {{ dorm.dorm_date_updated }}</div>
<div><br/></div>
<h4><b>House Rules</b></h4>
<div>{{dorm.dorm_house_rules}}</div>
{% endblock %}
Add the room_numbers to the template context by utilizing the object the DetailView provides and its related manager: joining the strings returned by values_list() with a comma.
class DormsDetailView(LoginRequiredMixin, generic.DetailView):
model = Dorm
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['room_numbers'] = ", ".join(self.object.dormroom_set.values_list('room_number', flat=True))
return context
Then adjust the template accordingly:
<div><br/></div>
<div>Available Rooms: {{ dorm.dorm_room_count}}</div>
<div>Rooms: {{ room_numbers }}</div>
<div><br/></div>
<h4><b>Contact Details</b></h4>

Trouble with order.by('?') .first() to get random content in Django

Update #4:
The for loop in slider.html is currently not pulling content after the last update. Slider.html was randomized; however, I'm getting four of the same story and the urls are not going to their appropriate detailed view page anymore.
List.html has been fixed and is now random.
slider.html - This section is still wonky, (updated - 4:19 p.m.)
{% for random_article in random_articles %}
<div class="slider">
<div class="group visible">
<div class="sliderItem">
<img src="{{random_article.relatedImage}}" alt="" class="sliderPicture">
<p class="related">{{random_article.title}}</p>
</div><!-- /.sliderItem -->
</div><!-- /.group -->
</div><!-- /.slider -->
{% endfor %}
Here is the URL error when I click to detailed view:
NoReverseMatch at /last-us
Reverse for 'detailed' with arguments '()' and keyword arguments '{u'slug': ''}' not found. 1 pattern(s) tried: ['(?P<slug>\\S+)']
New culprits (for why slider.html isn't working)
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns(
'',
url(r'^$', views.BlogIndex.as_view(), name="list"),
url(r'^(?P<slug>\S+)', views.BlogDetail.as_view(), name="detailed"),
)
views.py (updated - 4:19 p.m.)
Added context['random_slider'] = FullArticle.objects.order_by('?')[:4] but I don't think this is the right approach. So that I can get four different articles vs. four of the same article randomized.
from django.views import generic
from . import models
from .models import FullArticle
# Create your views here.
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def get_context_data(self, **kwargs):
context = super(BlogIndex, self).get_context_data(**kwargs)
context['random_article'] = FullArticle.objects.order_by('?').first()
return context
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['object_list'] = models.FullArticle.objects.published()
return context
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['random_articles'] = FullArticle.objects.exclude(
pk=self.get_object().pk
).order_by('?')[:4]
return context
Original Problem
I'm using FullArticle.objects.order_by('?').first() to get a random article from my database, but it's currently giving the same article when I refresh the page. There is probably something missing from my models, view or how I'm calling it (using slice) in list.html or slider.html that is causing the problem.
The two parts I'm looking to make random on page load:
list.html (changed so that it's {{random_article.}} ) - This section of the problem is fixed.
<div class="mainContent clearfix">
<div class="wrapper">
<h1>Top 10 Video Games</h1>
{% for article in object_list|slice:":1" %}
<p class="date">{{article.pubDate|date:"l, F j, Y" }}</p> | <p class="author">{{article.author}}</p>
<img src="{{article.heroImage}}" alt="" class="mediumImage">
<p class="caption">{{article.body|truncatewords:"80"}}</p>
{% endfor %}
models.py
from django.db import models
from django.core.urlresolvers import reverse
# Create your models here.
class FullArticleQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class FullArticle(models.Model):
title = models.CharField(max_length=150)
author = models.CharField(max_length=150)
slug = models.SlugField(max_length=200, unique=True)
pubDate = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
category = models.CharField(max_length=150)
heroImage = models.CharField(max_length=250, blank=True)
relatedImage = models.CharField(max_length=250, blank=True)
body = models.TextField()
publish = models.BooleanField(default=True)
gameRank = models.CharField(max_length=150, blank=True, null=True)
objects = FullArticleQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("FullArticle_detailed", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog entry"
verbose_name_plural = "Blog Entries"
ordering = ["-pubDate"]
The problem is that you are setting the value of a class attribute at "compile time" and not each time the view is called. Instead, you could do:
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def random_article(self):
return = FullArticle.objects.order_by('?').first()
Or:
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def get_context_data(self, **kwargs):
context = super(BlogIndex, self).get_context_data(**kwargs)
context['random_article'] = FullArticle.objects.order_by('?').first()
return context
[update]
In list html, I only need one random article. In slider.html, I need four random articles, would I just tack on FullArticle.objects.order_by('?')[:4] somewhere in that def get_context_data snippet?
Yes. Make it plural in the view (don't forget to exclude the main article from the side list):
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['random_articles'] = FullArticle.objects.exclude(
pk=self.get_object().pk
).order_by('?')[:4]
return context
At the template, do:
{% for random_article in random_articles %}
<div class="sliderItem">
<img src="{{random_article.relatedImage}}" alt="" class="sliderPicture">
<p class="related">{{random_article.title}}</p>
</div><!-- /.sliderItem -->
{% endfor %}
The generic listview just passes an object_list as context based on the queryset. In your case it means you have to either change the value of queryset in your view or override the get_context_data method and add your random item to it.
https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_context_data

Categories