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>
Related
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 %}
The task: To assign a single user to the model at a time.
The Error:
Django 'NoneType' object has no attribute 'filter'
The models.py is
class Post(models.Model):
post_tag = models.ForeignKey(ProjectUser, related_name="user_tag", blank=True, null=True,on_delete=models.CASCADE)
Where ProjectUser is:
from django.contrib.auth.models import AbstractUser
class ProjectUser(AbstractUser):
def __str__(self):
return self.username
The .html code is :
% for post_user in objects %}
<form method='POST' action="{% url 'a_tag' post_user.id %}">
{% csrf_token %}
<input type='hidden'>
{% if post_user.id in assigned_user %}
<button type='submit'>Cancel</button>
{% else %}
<button type='submit'>Start</button>
{% endif %}
</form>
The urls.py is
path('<int:tag>', views.tag_analyst, name='a_tag'),
The views.py function is <- Filter, add and remove attributes here are causing the errors
def tag_analyst(request, tag):
post = get_object_or_404(Post, id=tag)
if request.method == 'POST':
if post.post_tag.filter(id=request.user.id).exists():
post.post_tag.remove(request.user)
else:
post.post_tag.add(request.user)
return HttpResponseRedirect(reverse('homepage'))
The views.py class
class View(LoginRequiredMixin, ListView):
context_object_name = "objects"
model = Post
template_name = "page.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['assigned_user'] = self.request.user.user_tag.values_list('id', flat=True)
return context
post_tag is a ForeignKey field for Post, so post.post_tag is an object (or None in this case), but not a Manager. So you can't filter().
You can just check if post.post_tag. This will be True if a user is associated, and False (None) if not.
class Question(models.Model):
webregister = models.ForeignKey(Webregister, on_delete=models.CASCADE)
que = models.CharField(max_length=255,null=True, blank=True)
def __str__(self):
return str(self.pk)
orgs = Question.objects.filter(webregister=module,que__isnull=True)
orgs.delete()
I'm new to Django and web coding.
I'm following Bucky tuts: Django Tutorial for Beginners - 29 - Generic Views
& I'm trying to get my music ( index ) page , but it gives me that error in the browser :
AttributeError at /music/ type object 'Album' has no attribute
'object'
& here's my views.py :
from django.http import HttpResponse, Http404
from django.shortcuts import render , get_object_or_404
from .models import Album,song
from django.views import generic
"""
def index(request):
all_albums = Album.objects.all()
context = {'all_albums': all_albums}
return render(request, 'music/index.html', context)
"""
class IndexView (generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
return Album.object.all()
'''
class DetailView (generic.DetailView):
model = Album
template_name = "music/details.html"
'''
def details(request, album_id):
try:
album = Album.objects.get(pk=album_id)
except Album.DoesNotExist:
raise Http404("Album Does Not Exists !")
return render(request, 'music/details.html', {'album': album})
def favourite (request , album_id):
album = get_object_or_404 (Album , pk=album_id)
try:
selected_song = album.song_set.get(pk=request.POST['song'])
except(KeyError, song.DoesNotExist):
return render(request, 'music/details.html', {
'album':album,
'error_message': "you entered wrong"
})
else:
selected_song.is_favorite = False
selected_song.save()
return render(request,'music/details.html' , {'album':album})
models.py
from django.db import models
# Create your models here.
class Album (models.Model):
artist = models.CharField(max_length = 100)
album_title = models.CharField(max_length = 100)
genre = models.CharField(max_length = 50)
album_logo = models.CharField(max_length = 1000)
def __str__(self):
return self.album_title + " - " + self.artist
class song (models.Model):
album = models.ForeignKey(Album , on_delete=models.CASCADE)
file_type = models.CharField(max_length = 10)
song_title = models.CharField(max_length = 100)
is_favourite = models.BooleanField(default=False)
def __str__(self):
return self.song_title
index.html
{% extends 'music/base.html' %}
{% block title %}Main : MuSiC {% endblock %}
{% block body %}
<ul>
{% for album in all_albums %}
<li>{{ album.album_title }}</li>
{% endfor %}
</ul>
{% endblock %}
#/music/{{ album.id }}
project structure
{ (website) project dir }
|-music
..|-migrations
..|-static
..|-templates
....|-music
......|-base.html
......|-details.html
......|-index.html
|-__init__.py
|-admin.py
|-apps.py
|-models.py
|-tests.py
|-urls.py
|-views.py
|-website
..|-__init__.py
..|-settings.py
..|-urls.py
..|-wsgi.py
|-db.sqlite3
|-manage.py
and I don't know where is the problem :(
btw, lot's of coding terms I still didn't learned , that's why I may ask alot ever I searched for a solution but didn't understand the answer from other question's answers .
Album.object does not exist; you should've written Album.objects.
class IndexView (generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
# return Album.object.all() <-- Remove this
return Album.objects.all()
As a side note, reserved words cannot be python attributes. This is by design, because disallowing these words makes parsing substantially easier.
Why can't attribute names be Python keywords?
I need to create a required checkbox option if no_new_item exists. I am using the model.NullBoolean field. According to Django docs the Boolean field should render the checkbox widget but NullBoolean renders Select. The reason for the switch to NullBoolean was due to the null error when migrating. So now I am getting a drop down list with 'Yes' and 'No.'
How would I go about creating the checkbox in the Base model.Models with NullBoolean or is there a better way?
(this is an edit as I miss spoke about the Django Docs. Thanks #Alasdair)
/models.py
class StoreNightlyReport(models.Model):
store_number = models.ForeignKey('Stores', verbose_name='Store Number', max_length=20, null=True)
date = models.DateField(null=True)
#managers = models.ManyToManyField('auth.User', blank=True, null=True)
def __str__(self):
return self.store_number.store_number
class StoreNightlyReportsBase(models.Model):
store_nightly_report = models.ForeignKey(StoreNightlyReport)
no_new_item = models.NullBooleanField(verbose_name='No New Items', default=True)
customer = models.CharField(verbose_name='Customer Name', max_length=20, null=True)
class Meta:
abstract = True
/forms.py
class StoreNightlyReportsForm(ModelForm):
class Meta:
model = StoreNightlyReport
widgets = {'date': SelectDateWidget()}
exclude = ()
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(StoreNightlyReportsForm, self).__init__(*args, **kwargs)
if 'store_number' in self.fields:
if not user.is_superuser:
self.fields['store_number'].queryset = Stores.objects.filter(managers=user)
/views.py
class StoresNightlyReportsNewLoansCreate(CreateView):
template_name = 'reports/storenightlyreport_form.html'
model = StoreNightlyReport
form_class = forms.StoreNightlyReportsForm
success_url = reverse_lazy('reports:storenightlyreports')
def get_form(self, form_class=None):
form_class = self.get_form_class()
form = form_class(self.request.POST or None, user=self.request.user)
self.formsets = {}
StoreNightlyReportsNewLoanFormSet = inlineformset_factory(StoreNightlyReport,
StoreNightlyReportsNewLoan,
exclude=[],
extra=1)
self.formsets['new_loan'] = StoreNightlyReportsNewLoanFormSet(self.request.POST or None)
def get_context_data(self, **kwargs):
data = super(StoresNightlyReportsNewLoansCreate, self).get_context_data(**kwargs)
data['formset_new_loan'] = self.formsets['new_loan']
return data
def get_context_data(self, **kwargs):
data = super(StoresNightlyReportsNewLoansCreate, self).get_context_data(**kwargs)
#formset_renewal = StoreNightlyReportsRenewalFormSet()
data['formset_new_loan'] = self.formsets['new_loan']
return super(StoresNightlyReportsNewLoansCreate, self).form_invalid(form)
/template.html
{% extends "reports/base.html" %}
{% load static %}
{% block body_block %}
<div class="container-fluid">
<form class="form-inline" action="" method="post">
{% csrf_token %}
{{ form }}
<table class="table">
{{ formset_new_loan.management_form }}
<div>
<br><h4><strong>New Loans</strong></h4><br>
{% include "reports/formsets.html" with formset=formset_new_loan formset_class_name='new_loan' %}
</div>
</table>
Fixed
After some thought I just went back to the model.Base and changed it to the BooleanField type and added a default value. This cleared the null error on migration and rendered a checkbox option.
class StoreNightlyReportsBase(models.Model):
store_nightly_report = models.ForeignKey(StoreNightlyReport)
no_new_item = models.BooleanField(verbose_name="Check if No New Items", default=False)
customer = models.CharField(verbose_name='Customer Name', max_length=20, null=True)
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