I am building a site with the logic of Course - Section- Lesson. I can shoot the sections of the course, but I cannot shoot the lessons of the sections. Where am I doing wrong?
Models.py
class CourseCategoryModel(models.Model):
name = models.CharField(max_length=200, verbose_name="Category Name")
slug = models.SlugField(unique=True)
class CourseModel(models.Model):
name = models.CharField(max_length=200, verbose_name="Course Name")
category = models.ForeignKey(CourseCategoryModel, null=True, blank=True, on_delete=models.PROTECT, verbose_name="Course Category")
class CourseLessonSectionModel(models.Model):
name = models.CharField(max_length=200, verbose_name="Section Name")
order = models.IntegerField(max_length=3, verbose_name="Section Order")
course = models.ForeignKey(CourseModel, null=True, blank=True, on_delete=models.PROTECT, verbose_name="Course")
class CourseLessons(models.Model):
course = models.ForeignKey(CourseModel, null=True, blank=True, on_delete=models.CASCADE, verbose_name="Course")
section = models.ForeignKey(CourseLessonSectionModel, null=True, blank=True, on_delete=models.CASCADE, verbose_name="Lesson Section")
name = models.CharField(max_length=200, verbose_name="Lesson Name")
order = models.IntegerField(max_length=3 , verbose_name="Lesson Order", default=0)
View.py
def detail(request, slug):
course = CourseModel.objects.get(slug=slug)
courseSection = CourseLessonSectionModel.objects.all().filter(course__slug=slug)
courseLessons = CourseLessons.objects.all().filter("what should i write here?")
return render(request, "coursedetail.html", context={
"course": course,
"courseLessons" : courseLessons,
"courseSection" : courseSection
})
You have made ManyToOne relationship which is ForeignKey for everything.
You want to fetch lesson of the sections. I am assuming that you already fetched course and courseSection correctly.
You can __in lookup to filter on all sections' ids with particular course, so:
from django.db.models import Q
def detail(request, slug):
course = CourseModel.objects.get(slug=slug)
courseSection = CourseLessonSectionModel.objects.all().filter(kurs__slug=slug)
course_section_list=list(courseSection)
courseLessons = CourseLessons.objects.filter(Q(course=course) & Q(section__in=[i.id for i in course_section_list]))
return render(request, "coursedetail.html", context={
"course": course,
"courseLessons" : courseLessons,
"courseSection" : courseSection
})
Related
What I am working on is saving a new listing that is created by a given user on my commerce site, and displaying/redirecting the user to my index page. For some reason, the view keeps returning None and I'm not exactly sure why. Here is the code snippets below:
views.py
def createListing(request):
if request.method == "POST":
listing = NewListingForm(request.POST)
if listing.is_valid():
creator = request.user
title = listing.cleaned_data['title']
price = listing.cleaned_data['price']
description = listing.cleaned_data['description']
image = listing.cleaned_data['image']
category = listing.cleaned_data['category']
# Using .objects.create much simpler solution
auction = Listing.objects.create(
creator=creator,
title=title,
description=description,
price=price,
category=category,
image=image,
)
starting_bid = auction.price
bid = Bid.objects.create(
bid=starting_bid,
user=creator,
auction=auction
)
return render(request, "auctions/index.html", {
"message": "Listing Created Successfully."
})
if request.method == "GET":
return render(request, "auctions/create.html", {
"create_form": NewListingForm()
})
models.py
class User(AbstractUser):
pass
class Comment(models.Model):
comment = models.CharField(max_length=64)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_comment")
class Listing(models.Model):
CATEGORIES = [
('Toys', 'Toys'),
('Electronics', 'Electronics'),
('Lifestyle', 'Lifestyle'),
('Home', 'Home'),
('Fashion', 'Fashion'),
('Other', 'Other')
]
creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="creator")
title = models.CharField(max_length=64, blank=False, null=False)
price = models.DecimalField(max_digits=10, decimal_places=2, blank=False, null=True)
description = models.CharField(blank=True, max_length=1064, null=True)
category = models.CharField(max_length=64, blank=True, choices=CATEGORIES)
image = models.URLField(default='https://user-images.githubusercontent.com/52632898/161646398-6d49eca9-267f-4eab-a5a7-6ba6069d21df.png')
starting_bid = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
bid_counter = models.IntegerField(default=0)
active = models.BooleanField(default=True)
winner = models.CharField(max_length=64, blank=True, null=True)
def _str__(self):
return f"{self.title} by {self.creator}"
class Bid(models.Model):
bid = models.DecimalField(decimal_places=2, max_digits=10)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_bid")
date_created = models.DateTimeField(auto_now=True)
auction = models.ForeignKey(Listing, on_delete=models.CASCADE)
def __str__(self):
return f"{self.bid} made by {self.user}"
The new listing form:
# Creating a new listing form
class NewListingForm(forms.Form):
title = forms.CharField(label='', min_length=2, widget=forms.TextInput(
attrs={"class": "form-control", "style": "margin-bottom: 10px", "placeholder": "Title"}))
description = forms.CharField(label='', widget=forms.Textarea(
attrs={"class": "form-control", "style": "margin-bottom: 10px", "placeholder": "Description"}))
price = forms.DecimalField(label='', widget=forms.NumberInput(
attrs={"class": "form-control", "style": "margin-bottom: 10px", "placeholder": "Starting Bid ($)"}))
image = forms.ImageField(label="Choose an Image for your Listing")
category = forms.MultipleChoiceField(
label='Pick a Category', widget=forms.CheckboxSelectMultiple, choices=Listing.CATEGORIES)
I have tried looking into urls.py to ensure I was calling the right view with its according name and using 'return redirect('index')' but it doesn't seem to work either. I'm relatively new to django so any help would be appreciated! Let me know if there are any other files that are required to help clarify the problem.
Django handled http GET method automatically not needing to write it, and also need to remove the unwanted stuff.
your code becomes like this...
from django.shortcuts import render,redirect
from django.contrib import messages
def createListing(request):
listing =NewListingForm()
if request.method == "POST":
listing = NewListingForm(request.POST)
if listing.is_valid():
creator = request.user
title = listing.cleaned_data['title']
price = listing.cleaned_data['price']
description = listing.cleaned_data['description']
image = listing.cleaned_data['image']
category = listing.cleaned_data['category']
# Using .objects.create much simpler solution
auction = Listing.objects.create(
creator=creator,
title=title,
description=description,
price=price,
category=category,
image=image,
)
starting_bid = auction.price
bid = Bid.objects.create(
bid=starting_bid,
user=creator,
auction=auction
)
messages.success(request,"Listing Created Successfully")
return redirect("/home/")
context = {
"listing": listing
}
return render(request, "auctions/create.html", context)
I want to calculate most popular post by each category, but i have this error DISTINCT ON fields is not supported by this database backend.
after i use PostgreSql, but I also had a error. annotation and distinct together did not work.
model -->
class Category(models.Model):
title = models.CharField(max_length=150, verbose_name=_("კატეგორია"))
def __str__(self):
return self.title
class Question(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name=_("მომხმარებელი")
)
category = models.ManyToManyField(Category)
title = models.CharField(max_length=150, verbose_name=_("სათაური"))
body = models.TextField(verbose_name=_("ტექსტი"))
image = models.ImageField(blank=True, null=True, verbose_name=_("ფოტო"))
link = models.URLField(
max_length=400,
blank=True,
null=True,
validators=[RequireHttpOrHttpsUrl()],
verbose_name=_("ლინკი"),
)
time = models.DateTimeField(auto_now=True)
send_notification = models.BooleanField(
default=True, verbose_name=_("გავაგზავნოთ შეტყობინება?")
)
def __str__(self):
return self.title
class LikeDislike(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name=_("მომხმარებელი")
)
question = models.ForeignKey(
Question, on_delete=models.CASCADE, verbose_name=_("კითხვა")
)
point = models.BooleanField()
time = models.DateTimeField()
def __str__(self):
return self.question.title
view ->
class CountLikeByCategory(generics.ListCreateAPIView):
serializer_class = CountLikeByCategorySerializer
def get_queryset(self):
query=Question.objects.values_list(
'category__title','title'
).annotate(
l=Count('likedislike',filter=Q(likedislike__point=1)),
d=Count('likedislike',filter=Q(likedislike__point=0)),
total=F('l')+F('d'),
).order_by('category', '-total').distinct('category')
return query
who can help me?
i wan correct query
try this:
def get_queryset(self):
query=Question.objects.values_list(
'category','category__title','title'
).annotate(
l=Count('likedislike',filter=Q(likedislike__point=1)),
d=Count('likedislike',filter=Q(likedislike__point=0)),
total=F('l')+F('d'),
).order_by('category', '-total').distinct('category')
return query
[![Nurse admin page[![][1]][1][models.py
from django.db import models
#Work Related aka Department and Work Shift
class Department(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
def __str__(self):
return self.name
class WorkShift(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
start_datetime = models.DateTimeField(null=True, blank=True)
end_datetime = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.name
#Personel Related aka Employees and Patients
class Doctor(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Nurse(models.Model):
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
reports_to = models.OneToOneField(Doctor, default="", blank=True, null=True, on_delete=models.CASCADE)
work_shift = models.OneToOneField(WorkShift, default="", blank=True, null=True, on_delete=models.CASCADE)
def __str__(self):
return str(name)
class Patient(models.Model):
STATUS = (
('Sick', 'Sick'),
('Healing', 'Healing'),
('Cured', 'Cured'),
('Deceased', 'Deceased'),
)
name = models.CharField(max_length=200, null=True, blank=True)
description = models.TextField(blank=True, null=True)
status = models.CharField(max_length=200, null=True, blank=True, choices=STATUS)
department = models.ForeignKey(Department, default="", null=True, blank=True, on_delete=models.CASCADE)
care = models.ForeignKey(Nurse, default="", blank=True, null=True, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return self.name
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from .models import Doctor, Nurse, Patient
from django.http import HttpResponse
# Create your views here.
def index(request):
patient = Patient.objects.all()
nurse = Nurse.objects.all()
doctor = Doctor.objects.all()
total_patient = patient.count()
sick = patient.filter(status='Sick').count()
healing = patient.filter(status='Healing').count()
cured = patient.filter(status='Cured').count()
total_nurse = nurse.count()
# if request.method == 'POST':
# form =
context = {
'patient':patient, 'nurse':nurse,
'doctor':doctor, 'total_patient':total_patient,
'sick':sick, 'healing':healing, 'cured':cured,
'total_nurse':total_nurse
}
return render(request, 'lifesaver/index.html', context)
def patient(request):
patient = Patient.objects.all()
total_patient = patient.count()
context = {
'patient':patient,
'total_patient':total_patient
}
return render(request, 'lifesaver/patient.html', context)][1]
forms.py
from django import forms
from .models import Doctor, Nurse, Patient
from django.auth.contrib.forms import UserCreationForm
class DoctorForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Doctor',
'class': 'form-control'
}
))
department = forms.ModelChoiceField(queryset=department.objects.all)
class NurseForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Nurse',
'class': 'form-control'
}
))
class PatientForm(forms.ModelForm):
name = forms.CharField(widget = forms.TextInput(attrs =
{
'placeholder': 'Add a New Patient'
'class': 'form-control'
}))
HTML for patient
{% extends 'lifesaver/main.html' %}
{% block content %}
<h1>SUPERSTAR</h1>
{% for patient in patient %}
{{patient.name}}
{% endfor %}
{% endblock content %}
I get this error when I go to try to add another Nurse. The URL is http://127.0.0.1:8000/admin/lifesaver/nurse/add/. Everything else behaves as expected, except the adding the Nurse part.
If I try to remove the def __str___ part, the error still displays. I believe the error lies in the:
work_shift = models.OneToOneField(WorkShift, default="",
blank=True,
null=True,
on_delete=models.CASCADE)
part since when I included that code, the error spawned. Furthermore, the code is to add a work shift to certain employees and the goal is that the employees shift will display in their profile.
How do I fix this issue?
EDIT: When accessing the HTML template, the web page behaves as expected and has no issues.
In your Nurse model replace this:
def __str__(self):
return str(Nurse.name)
with this:
def __str__(self):
return self.name
I am new to Django and Python. I am trying to create a database of babysitters and one of the objects which can have multiple fields is Education. My first Babysitter has 2 qualifications which produces an error an will not display.
Error Message
views.py
from django.shortcuts import render, get_object_or_404, get_list_or_404
from .models import Babysitter, Education, Work, Reference
# Create your views here.
def all_babysitters(request):
babysitters = Babysitter.objects.all()
return render(request, "babysitters.html", {"babysitters": babysitters})
def babysitter_profile(request, id):
"""A view that displays the profile page of a registered babysitter"""
babysitter = get_object_or_404(Babysitter, id=id)
reference = get_object_or_404(Reference)
education = get_object_or_404(Education)
return render(request, "babysitter_profile.html", {'babysitter': babysitter, 'education': education, 'reference': reference} )
models.py
from django.db import models
from datetime import datetime
# Create your models here.
class Babysitter(models.Model):
list_display = ('firstName', 'lastName', 'minderType')
firstName = models.CharField(max_length=50, blank=True, null=True)
lastName = models.CharField(max_length=50, blank=True, null=True)
minderType = models.CharField(max_length=50, blank=True, null=True)
image = models.ImageField(upload_to='images')
phone = models.CharField(max_length=20, blank=True, null=True)
email = models.CharField(max_length=50, blank=True, null=True)
address1 = models.CharField(max_length=100, null=True)
address2 = models.CharField(max_length=100, null=True)
city = models.CharField(max_length=20, null=True)
county = models.CharField(max_length=100, null=True)
eircode = models.CharField(max_length=7, null=True)
biography = models.TextField(max_length=280,blank=True)
def __str__(self):
return self.firstName + ' ' + self.lastName
class Education(models.Model):
babysitter = models.ForeignKey(Babysitter)
school = models.CharField(max_length=50)
qualification = models.CharField(max_length=50)
fieldOfStudy = models.CharField(max_length=50)
dateFrom = models.DateField(auto_now=False, auto_now_add=False)
dateTo = models.DateField(
auto_now=False, auto_now_add=False, null=True, blank=True)
current = models.BooleanField(default=False)
graduated = models.BooleanField(default=False)
def __str__(self):
return self.school
class Work(models.Model):
babysitter = models.ForeignKey(Babysitter)
family = models.CharField(max_length=50)
role = models.CharField(max_length=50)
location = models.CharField(max_length=50)
dateFrom = models.DateField(auto_now=False, auto_now_add=False)
dateTo = models.DateField(
auto_now=False, auto_now_add=False, null=True, blank=True)
current = models.BooleanField(default=False)
def __str__(self):
return self.work
class Reference(models.Model):
babysitter = models.ForeignKey(Babysitter)
refFamily = models.CharField(max_length=50)
contact = models.CharField(max_length=50)
location = models.CharField(max_length=50)
email = models.CharField(max_length=50, blank=True, null=True)
reference = models.CharField(max_length=300)
date = models.DateField(auto_now=False, auto_now_add=False)
def __str__(self):
return self.refFamily
Can somebody help? I am going to pull my hair out. Thanks
You aren't passing enough information into the calls to get a Reference and Education object:
babysitter = get_object_or_404(Babysitter, id=id)
reference = get_object_or_404(Reference, babysitter_id=babysitter.id)
education = get_object_or_404(Education, babysitter_id=babysitter.id)
The get_object_or_404() function is a shortcut that calls get() underneath, and get() only ever returns a single object (returning more than one will result in the Exception you are seeing).
If you want to see more than one object, then don't use the get_object_or_404 shortcut method (I find those "shortcut" methods to be ugly, personally). Instead, change it to something like:
education_qs = Education.objects.filter(babysitter_id=babysitter.id)
Then loop over that queryset to get the results:
for ed in education_qs:
# Get some data
school = ed.school
You can loop over the queryset in your HTML template, if that's easier.
Update: Here's a better answer that shows how to use querysets:
def babysitter_profile(request, id):
"""A view that displays the profile page of a registered babysitter"""
babysitter = get_object_or_404(Babysitter, id=id)
reference_qs = Reference.objects.filter(babysitter_id=babysitter.id)
education_qs = Education.objects.filter(babysitter_id=babysitter.id)
return render(request, "babysitter_profile.html", {
'babysitter': babysitter,
'education_qs': education_qs,
'reference_qs': reference_qs}
)
Then, in your HTML template, you could do something like the following to show the schools the Babysitter has attended (in a bulleted list):
<ul>
{% for ed in education_qs %}
<li>{{ ed.school }}</li>
{% endfor %}
</ul>
You could do something similar for the Reference data.
I think you should set some parameters to get a specific object, rather than get a bunch of objects.
Just do it like the first instance for get_object_or_404.
reference = get_object_or_404(Reference,id=xx)
education = get_object_or_404(Education,id=yy)
get_object_or_404 returns just 1 object. Use get_list_or_404 if babysitter has "2 qualification" to prevent exception.
babysitter = get_object_or_404(Babysitter, id=id)
education = get_list_or_404(Education, id=babysitter.id)
To prevent MultipleObjectReturned exception.
So I need to filter posts, posted by users, who the user currently logged in is following.
Here's my models:
class ProfileDetails(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
provider = models.CharField(max_length=20, null=True, blank=True)
firstname = models.CharField(max_length=25, null=True, blank=True)
lastname = models.CharField(max_length=25, null=True, blank=True)
username = models.CharField(max_length=24, null=True, blank=True, unique=True)
def __str__(self):
return str(self.user)
class Posts(models.Model):
post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(ProfileDetails, on_delete=models.CASCADE, null=True)
text = models.TextField(max_length=280, null=True, blank=True)
video = models.CharField(max_length=24, null=True, blank=True)
timestamp = models.DateTimeField(default=datetime.datetime.now, blank=True)
def __str__(self):
return str(self.user)
class Connection(models.Model):
follower = models.ForeignKey(ProfileDetails, related_name='follower', on_delete=models.SET_NULL, null=True)
following = models.ForeignKey(ProfileDetails, related_name='following', on_delete=models.SET_NULL, null=True)
# follower = models.ManyToManyField(ProfileDetails, related_name='follower')
# following = models.ManyToManyField(ProfileDetails, related_name='following')
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return str(self.follower)
And then in my views, my bit of Python / Django knowledge kind of directed me to write something like this (take a look particularly at the last bit, where I try to filter it so it only gets details from the users I follow.
def index(request):
checkuser = request.user
print(checkuser)
if ProfileDetails.objects.filter(user=checkuser):
print("user previously logged in")
sns = get_object_or_404(SocialAccount, user=checkuser)
autoupdateprofile = get_object_or_404(ProfileDetails, user=checkuser)
autoupdateprofile.lastlogin = datetime.datetime.now()
autoupdateprofile.save(update_fields=["lastlogin"])
# print(sns.provider)
details = get_object_or_404(ProfileDetails, user=checkuser)
videos = Posts.objects.filter(media=True, imade=True).order_by("-timestamp")[0:6]
followercount = Connection.objects.filter(follower=details).count()
follows = Connection.objects.filter(follower=details)
followerposts = Posts.objects.filter(user=follows)
for a in followerposts:
print(a)
return render (request, 'index.html', context)
However, this doesn't seem to work. I'm greeted with this lovely error trying to get me to use the data from the model ProfileDetails - which would obviously make no sense, cause how else can I indicate the users I'm following in Connections.
Exception Value:
Cannot use QuerySet for "Connection": Use a QuerySet for "ProfileDetails".
Been struggling with this for a few days and no longer sure what to search for.
If it makes any difference, I'm using Python 3.6 and Django 2.0.4 on Postgresql.
Suggestions would be appreciated. :)
Thanks in advance.
Ronald
This code goes in and fetches all posts from users whom the current user follows (ie, for whom the current user is a follower):
Posts.objects.filter(user__following__follower=ProfileDetails.objects.get(user=self.request.user))