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.
Related
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
})
My problem is have two models job and company and i want to get all jobs in this company
My urls.py:
url(r'^jobs/(?P<slug>[\w-]+)/$', views.job_at_company, name='job_at_company'),
My views.py:
def job_at_company(request, slug):
return render(request, 'jobs.html')
My models.py:
class Company(models.Model):
title = models.CharField(max_length=100, blank=False)
slug = models.SlugField(blank=True, default='')
city = models.CharField(max_length=100, blank=False)
contact_info = models.CharField(max_length=100, blank=False, default=0)
facebook = models.CharField(max_length=100, blank=True)
twitter = models.CharField(max_length=100, blank=True)
linkedin = models.CharField(max_length=100, blank=True)
logo = models.ImageField(upload_to="logo", default=0)
class Jobs(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True, default='')
company = models.ForeignKey(Company, on_delete=models.CASCADE)
price = models.IntegerField(default='')
Description = models.TextField(blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
job_type = models.CharField(max_length=100, choices=(('Full Time', 'Full Time'),('Part Time', 'Part Time')),default='Full Time')
in the views.py we can add this
def job_at_company(request, slug):
results = Jobs.objects.filter(company__slug=slug)
context = {'items':results}
return render(request, 'jobs.html',context)
Suppose you pass id in the url. The id is the primary key of the company. You would have to modify your url to accept id like -
url(r'^jobs/(?P<slug>[\w-]+)/(?P<pk>[\d]+)$', views.job_at_company, name='job_at_company')
And modify your views.py -
def job_at_company(request, slug, pk):
jobs_qs = Jobs.objects.filter(company__id=pk)
return render(request, 'jobs.html', {'jobs': jobs_qs})
And use it in your html like -
{% for job in jobs %}
{{job.title}}
{% endfor %}
Look at this link. Django's documentation is helpful, follow that
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))
I'm relatively new in python/django thing. Having 3 models with some fields for example:
class Card(models.Model):
id = models.AutoField(primary_key=True)
cardtype_id = models.CharField(max_length=10)
holder_name = models.CharField(max_length=100)
card_number = models.IntegerField(default=0)
email = models.EmailField(blank=True)
birthday = models.DateField(blank=True, default=None)
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(default=timezone.now)
strip = models.CharField(max_length=20, default="strip")
def __str__(self):
return self.holder_name
class Transaction(models.Model):
id = models.AutoField(primary_key=True)
description = models.CharField(max_length=100)
class CardTransactions(models.Model):
card = models.ForeignKey(Card, on_delete=models.CASCADE)
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
value = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
value_date = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(default=timezone.now)
description = models.CharField(max_length=200, blank=True)
table_value = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
discount = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
net_value = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
doc_number = models.CharField(max_length=20, blank=True)
How can I ask the user to input, for example, the "card_number" and print out the "description" on a HTML page?
from django.forms import model_to_dict
def my_view(request):
card_num = request.GET.get('cc')
return HttpResponse(str(model_to_dict(Card.objects.filter(card_number=card_num).first()))
at least something like that
You will need to write views and templates to do this task.
One view would be to render the html template where you will have a form to input the value.
Clicking on the button will call another view with parameter card_number which will retrieve the description from the database associated with the card_number and return back to the template where the same can be shown with some div as per your design.
Ajax can be used to call the view and fetch the response.
See below links for reference:
https://docs.djangoproject.com/en/2.0/intro/tutorial03/
https://docs.djangoproject.com/en/2.0/intro/tutorial04/
I created models called Interview, Users, Interview_interviewer like wise...
Interview_interviewer table has foreign keys from other models.
I just want to save data from both 2 tables to Interview_interviewer(Without django forms) table which is many to many table. So I just created the views and template for it. When button clicks it save the Interviewers to table along side with the interview. But when do it, It gave me and error called "User matching query does not exist".
/home/govinda/DMG/test3/myapp/views.py in hod_inter_interviewer_2
usr = User.objects.get(id=pid)
What should I do?
class Interview(models.Model):
Time = models.TimeField()
Date = models.DateField()
Venue = models.ForeignKey('Venue')
HOD = models.ForeignKey(User)
Vacancy = models.ForeignKey('Vacancy', on_delete=models.CASCADE)
Department = models.ForeignKey(Department, on_delete=models.CASCADE)
InterviewType = models.ForeignKey(InterviewType, on_delete=models.CASCADE)
Interviewer_Review = models.TextField(blank=True, null=True)
HOD_Review = models.TextField(blank=True, null=True)
HR_Review = models.TextField(blank=True, null=True)
NoOfPasses = models.PositiveIntegerField(blank=True, null=True)
NoOfFails = models.PositiveIntegerField(blank=True, null=True)
NoOfOnHolds = models.PositiveIntegerField(blank=True, null=True)
InterviewNo = models.IntegerField(blank=True, null=True)
Post = models.ForeignKey(Post, on_delete=models.CASCADE)
and
class Users(models.Model):
User = models.OneToOneField(User)
FullName = models.CharField(max_length=100)
Post = models.ForeignKey(Post)
UPhoto = models.FileField(upload_to=User_directory_path,null = True,blank=True)
Department = models.ForeignKey(Department)
UserRole = models.ForeignKey(UserRole)
def __str__(self):
return u'{}'.format(self.User)
and
class Interview_Interviewer(models.Model):
Interview = models.ForeignKey(Interview)
Interviewer = models.ForeignKey(User)
def __str__(self):
return u'{}'.format(self.Interviewer)
views are...
def hod_pre_interviwer_list(request, iid):
inter = Interview.objects.get(id=iid)
a = UserRole.objects.get(Role="Interviewer")
viewer = Users.objects.filter(UserRole=a.id)
return render(request, 'hod_inter_create_2.html', {'viewer': viewer, 'inter': inter, 'a':a})
def hod_inter_interviewer_2(request, iid, pid):
inter = Interview.objects.get(id=iid)
usr = User.objects.get(id=pid)
a = UserRole.objects.get(Role="Interviewer")
viewer = Users.objects.filter(UserRole=a.id)
usr_id = Users.objects.get(User=a.id)
inter_id = inter
person_id = usr_id
form = Interview_Interviewer(Interview=inter_id, Interviewer=person_id)
form.save()
return render(request, 'hod_inter_create_2.html', {'viewer': viewer, 'inter': inter})
urls are...
urlpatterns = [
url(r'^hod/hod_vacancy/test/part2/inter_list/(\d+)/$', hod_pre_interviwer_list, name="inter1"),
url(r'^hod/hod_vacancy/test/part2/inter_list/(\d+)/(\d+)/$', hod_inter_interviewer_2, name="inter2"),
]
template is...
<a type="submit" class="btn btn-primary" href="/hod/hod_vacancy/test/part2/inter_list/{{ inter.id }}/{{ viewer.id }}">Add</a>
Try using named groups in your url patterns
urlurl(r'^hod/hod_vacancy/test/part2/inter_list/?P<iid>[0-9]+)/?P<pid>[0-9]+/$', hod_inter_interviewer_2, name="inter2"),
If that doesn't work then i suggest trying User.object.get(pk=pid) as in most doc examples.
And make sure that there is a user with that id (iid) in the url.
You should also use get_object_or_404 for getting any single object from a model in the view as it gives a more user friendly and appropriate error.