I am not that good at queries, so I need some help. I have a Course model, and a TeacherData model. Each teacher has its own courses. But when a teacher makes an account I use a Teacher model. And if teacher_ID column from TeacherData doesn't match the one entered by the user, the account cannot be created.
Now, in my form I need to show Courses for each teacher, so that a Lecture instance can be created. I was thinking to use teacher_ID as bridge connecting Teacher model with TeacherData model and then I would be able to show the courses that only a specific teacher has.
This is what I tried, but can't figure out:
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=30, null=True, blank=True, default=None)
surname = models.CharField(max_length=50, null=True, blank=True, default=None)
email = models.EmailField(unique=True, null=True, blank=True, default=None)
teacher_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')],
null=True, blank=True, default=None)
class Lecture(models.Model):
LECTURE_CHOICES = (
('Courses', 'Courses'),
('Seminars', 'Seminars'),
)
course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures',)
lecture_category = models.CharField(max_length=10, choices=LECTURE_CHOICES, default='Courses',)
lecture_title = models.CharField(max_length=100, blank=True, null=True)
content = models.TextField(blank=False, default=None)
class Course(models.Model):
study_programme = models.ForeignKey('StudyProgramme', on_delete=models.CASCADE, default='')
name = models.CharField(max_length=50, unique=True)
ects = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
description = models.TextField()
year = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
semester = models.IntegerField(choices=((1, "1"),
(2, "2"),
), default=None)
teacher1 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None,
verbose_name="Course Teacher", related_name='%(class)s_course_teacher')
teacher2 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None, null=True,
verbose_name="Seminar Teacher", related_name='%(class)s_seminar_teacher')
class TeacherData(models.Model):
name = models.CharField(max_length=30)
surname = models.CharField(max_length=50)
teacher_ID = models.CharField(unique=True, max_length=14)
notes = models.CharField(max_length=255, default=None, blank=True)
Run code snippetExpand snippet
class LectureForm(forms.ModelForm):
lecture_title = forms.CharField(max_length=100, required=True)
course = forms.ModelChoiceField(initial=Course.objects.first(), queryset=Course.objects.filter(
Q(teacher1__surname__in=[t.surname for t in TeacherData.objects.filter(
Q(teacher_ID__iexact=[x.teacher_ID for x in Teacher.objects.all()]))])))
class Meta:
model = Lecture
fields = ('course', 'lecture_category', 'lecture_title', 'content')
The expected behavior is when teacher is logged in, they would able to add a new lecture only for courses that they teach. I can achieve roughly the same effect by doing the following in a template
{% for data in teacher_data %}
{% if data.teacher_ID == user.teacher.teacher_ID %}
{% for course in courses %}
{% if course.teacher1 == data or course.teacher2 == data %}
<li>
{{ course.name }}
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
Related
I want to render data to my webpage from my django app however only two of the required slots are being rendered
my models are:
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=7, decimal_places=2)
digital = models.BooleanField(default=False,null=True, blank=True)
image = models.ImageField(null=True , blank=True)
description = models.TextField(max_length=5000, null=True)
points = models.DecimalField(max_digits=5,decimal_places=0, null=True)
and my views are
def admin_dashboard (request):
order_list = Order.objects.all()
context = {'order':order_list}
template = "admin_dashboard.html"
return render(request, 'store/admin_dashboard.html', context)
my HTML is:
{% extends 'store/admin_main.html' %}
{% load static %}
{% block content %}
{% for order in order %}
<h6>{{ order.transaction_id }}</h6>
<p>{{ order.customer }}</p>
<p>{{ order.shippingaddress }}</p>
<p>{{ order.orderitem }}</p>
{% endfor%}
{% endblock content %}
1598061443.212917
userNew
which is just the transaction id and user.
how can I have all the rest of fields filled
class Product(models.Model):
subcategory = models.ManyToManyField(Subcategory, related_name="Category")
name = models.CharField(max_length=32, unique=True)
title = models.CharField(max_length=3000)
ean = models.PositiveIntegerField(blank=True, null=True, unique=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, blank=True, null=True)
origin_name = models.CharField(max_length=32, blank=True, null=True)
quantity = models.PositiveIntegerField(blank=True, null=True)
highlights = models.TextField(max_length=3000, blank=True, null=True)
description = models.TextField(max_length=3000, blank=True, null=True)
delivery = models.TextField(max_length=3000, blank=True, null=True)
selling_price = models.DecimalField(max_digits=9, decimal_places=2)
slug = models.SlugField(unique=True)
class Infobox(models.Model):
name = models.CharField(max_length=32)
measurment = models.CharField(max_length=32)
resolution = models.CharField(max_length=32)
product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)
I would like to display on my detail page all infobox objects that are linked to the device, do any of you know how to do this?
THANKSSSS <3
urls.py
Add below to your urlpatterns:
path('view_infoboxes/<int:product_id>', views.view_infoboxes, name='view_infoboxes'),
views.py
def view_infoboxes(request, product_id):
template = loader.get_template('page.html')
context = {"infoboxes": Infobox.objects.filter(product=product_id)}
return HttpResponse(template.render(context, request))
page.html
...
<div class="row">
{% for infobox in infoboxes %}
<p>{{ infobox.name }}</p>
{% endfor %}
</div>
...
This is my current code in views.py
students = grade.objects.filter(Teacher=m.id).annotate(total_avg=Avg('Average')).prefetch_related('Subjects').order_by('Students_Enrollment_Records').distinct()
this is the result:
As you can see the 2 ROSE L TRiNIDAD exist, and it didn't compute the final ratings, but when I use the values()
students=grade.objects.values('Students_Enrollment_Records').filter(Teacher=m.id).annotate(total_avg=Avg('Average')).prefetch_related('Students_Enrollment_Records').order_by('Students_Enrollment_Records').distinct()
the result is
The distinct() method is applied and it computes the final ratings, but as you can see the name of the teacher, subject and the students didn't display.
This is my html:
{% for student in students %}
<tr>
<td>{{student.Teacher}}</td>
<td>{{student.Subjects}}</td>
<td>{{student.Students_Enrollment_Records}}</td>
<td>{{student.total_avg}}</td>
</tr>
{% endfor %}
My models.py:
class StudentsEnrolledSubject(models.Model):
Students_Enrollment_Records = models.ForeignKey(StudentsEnrollmentRecord, related_name='+',
on_delete=models.CASCADE, null=True)
Subject_Section_Teacher = models.ForeignKey(SubjectSectionTeacher, related_name='+', on_delete=models.CASCADE,
null=True)
class grade(models.Model):
Teacher = models.ForeignKey(EmployeeUser, related_name='+', on_delete=models.CASCADE,
null=True, blank=True)
Grading_Categories = models.ForeignKey(gradingCategories, related_name='+', on_delete=models.CASCADE,
null=True, blank=True)
Subjects = models.ForeignKey(Subject, related_name='+', on_delete=models.CASCADE, null=True)
Students_Enrollment_Records = models.ForeignKey(StudentsEnrolledSubject, related_name='+',
on_delete=models.CASCADE, null=True)
Average = models.FloatField(null=True, blank=True)
class EmployeeUser(models.Model):
Image = models.ImageField(upload_to='images', null=True, blank=True)
Employee_Number = models.CharField(max_length=500, null=True)
Username = models.CharField(max_length=500, null=True)
Password = models.CharField(max_length=500, null=True)
.
.
Note: this is a different question with the same result, How to use filtering data while using distinct method in django?
Can you please explain to me why when I use values() the name of the student display ID(56 and 57) only not the name, as shown in the image?
UPDATE when I use
students=grade.objects.values('Students_Enrollment_Records__Students_Enrollment_Records').filter(Teacher=m.id).annotate(total_avg=Avg('Average')).prefetch_related('Students_Enrollment_Records').order_by('Students_Enrollment_Records').distinct()
class StudentsEnrollmentRecord(models.Model):
Student_Users = models.ForeignKey(StudentProfile, related_name='students', on_delete=models.CASCADE, null=True)
School_Year = models.ForeignKey(SchoolYear, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
Courses = models.ForeignKey(Course, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
Section = models.ForeignKey(Section, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
Payment_Type = models.ForeignKey(PaymentType, related_name='+', on_delete=models.CASCADE, null=True)
Discount_Type = models.ForeignKey(Discount, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
Education_Levels = models.ForeignKey(EducationLevel, related_name='+', on_delete=models.CASCADE, blank=True,
null=True)
Remarks = models.TextField(max_length=500, null=True, blank=True)
the name of the teacher and student, subject are not displaying.
when i tried this
students=grade.objects.values('Teacher', 'Subjects', 'Students_Enrollment_Records').filter(Teacher=m.id).annotate(total_avg=Avg('Average')).prefetch_related('Students_Enrollment_Records').order_by('Students_Enrollment_Records').distinct()
this is the result
can you guys please explain to me why when i use values() the name of the student display ID(56 and 57) only not the name??
As docs says
The values() method takes optional positional arguments, *fields, which specify field names to which the SELECT should be limited
So when you call values('Students_Enrollment_Records') you got only this foreign key id in result
Add more fields in values() and you will get them in result too
For exsample if you need name of Students_Enrollment_Records model object and it is stored in model field name you should add 'Students_Enrollment_Records__name' to values()
In the end this solution was used for this case:
query
students = grade.objects.filter(Teacher=m.id).values('Teacher__Username', 'Subjects__Description', 'Students_Enrollment_Records__Students_Enrollment_Records__Student_Users__Username').annotate(total_avg=Avg('Average')).order_by('Students_Enrollment_Records').distinct()
html
{% for student in students %}
<tr>
<td>{{student.Teacher__Username}}</td>
<td>{{student.Subjects__Description}}</td>
<td>{{student.Students_Enrollment_Records__Students_Enrollment_Records__Student_Users__Username}}</td>
<td>{{student.total_avg}}</td>
</tr>
{% endfor %}
I'm trying to display data from my template. The issue I'm having is with the foreign key in the BattingStats table that references playerid of the PlayerInfo table. When I get it to display, the data for that field is showing but it is wrapped in parenthesis and preceded by ReferencedTable object. So for me it looks like this PlayerInfo object (smithjo05). Why would it be doing that and how would i get it to just show the playerid? Help is appreicated. Thanks.
VIEWS
def battingview(request):
playerinfo = PlayerInfo.objects.all()
playerstats = BattingStats.objects.filter(year=2018)
return render(request, 'playerstats/battingRegStnrd2018.html', {'playerinfo':playerinfo,'playerstats': playerstats})
MODELS
class BattingStats(models.Model):
id = models.IntegerField(db_column='ID', primary_key=True)
playerid = models.ForeignKey('PlayerInfo', models.DO_NOTHING, db_column='playerID', blank=True, null=True)
player = models.CharField(db_column='Player', max_length=255, blank=True, null=True)
hr = models.IntegerField(db_column='HR', blank=True, null=True)
rbi = models.IntegerField(db_column='RBI', blank=True, null=True)
ba = models.FloatField(db_column='BA', blank=True, null=True)
class PlayerInfo(models.Model):
playerid = models.CharField(db_column='playerID', primary_key=True, max_length=255)
namefirst = models.CharField(db_column='nameFirst', max_length=255, blank=True, null=True)
namelast = models.CharField(db_column='nameLast', max_length=255, blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
debut = models.CharField(max_length=255, blank=True, null=True)
finalgame = models.CharField(db_column='finalGame', max_length=255, blank=True, null=True)
HTML
{% for index in playerstats %}
<td>{{ index.playerid }}</td>
<td>{{ index.year}}</td>
<td>{{ index.age}}</td>
<td>{{ index.team}}</td>
<td>{{ index.league}}</td>
{% endfor %}
{% for index in playerstats %}
{{ index.playerid }}
{% endfor %}
Browser
PlayerInfo object (smithjo05)
PlayerInfo object (cruzne02)
PlayerInfo object (jonesad01)
You just need to add __str__ method to your PlayerInfo model:
class PlayerInfo(models.Model):
playerid = models.CharField(db_column='playerID', primary_key=True, max_length=255)
namefirst = models.CharField(db_column='nameFirst', max_length=255, blank=True, null=True)
namelast = models.CharField(db_column='nameLast', max_length=255, blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
debut = models.CharField(max_length=255, blank=True, null=True)
finalgame = models.CharField(db_column='finalGame', max_length=255, blank=True, null=True)
def __str__(self):
return self.playerid
This allows to change default representation of instance when you convert it to string, for example in templates.
So what I say might seem complicated, but I think the answer is easy. I just can't figure it out. I have a form for a Lecture model, which a logged in teacher can use to post a lecture for his specific courses only. Thing is that in my database I have a TeacherData model which contains a teacher_ID field used for verification, so a teacher cannot create his account on the other Teacher model, if teacher_ID entered doesn't match. But when a course is created in database, the teacher used is the one from TeacherData. So to create my query I have to filter the courses based on TeacherData and then using teacher_ID, to link to Teacher model. I just don't know how to build this queryset but I replicated the wanted behaviour in the template:
{% if user.is_authenticated and user.is_teacher %}
<ul>
{% for data in teacher_data %}
{% if data.teacher_ID == user.teacher.teacher_ID %}
{% for course in courses %}
{% if course.teacher1 == data or course.teacher2 == data %}
<li>
{{ course.name }}
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
{% endif %}
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=30, null=True, blank=True, default=None)
surname = models.CharField(max_length=50, null=True, blank=True, default=None)
email = models.EmailField(unique=True, null=True, blank=True, default=None)
teacher_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')],
null=True, blank=True, default=None)
class TeacherData(models.Model):
name = models.CharField(max_length=30)
surname = models.CharField(max_length=50)
teacher_ID = models.CharField(unique=True, max_length=14)
notes = models.CharField(max_length=255, default=None, blank=True)
class Lecture(models.Model):
LECTURE_CHOICES = (
('Courses', 'Courses'),
('Seminars', 'Seminars'),
)
course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures', )
lecture_category = models.CharField(max_length=10, choices=LECTURE_CHOICES, default='Courses', )
lecture_title = models.CharField(max_length=100, blank=True, null=True)
content = models.TextField(blank=False, default=None)
class Course(models.Model):
study_programme = models.ForeignKey('StudyProgramme', on_delete=models.CASCADE, default='')
name = models.CharField(max_length=50, unique=True)
ects = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
description = models.TextField()
year = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
semester = models.IntegerField(choices=((1, "1"),
(2, "2"),
), default=None)
teacher1 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None,
verbose_name="Course Teacher", related_name='%(class)s_course_teacher')
teacher2 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None, null=True,
verbose_name="Seminar Teacher", related_name='%(class)s_seminar_teacher')
class LectureForm(forms.ModelForm):
lecture_title = forms.CharField(max_length=100, required=True)
course = forms.ModelChoiceField(initial=Course.objects.first(), queryset=Course.objects.filter(
Q(teacher1__id__in=[t.id for t in TeacherData.objects.filter(
teacher_ID__iexact=[t.teacher_ID for t in Teacher.objects.all()])])))
class Meta:
model = Lecture
fields = ('course', 'lecture_category', 'lecture_title', 'content')
try this,
from django.contrib.auth.decorators import permission_required
from .models import Teacher
#permission_required( # permission class to check 'is_authenticated' and 'is_teacher')
def my_view(request):
queryset = Teacher.objects.filter(teacher_ID=request.user.teacher_ID)
if queryset:
# do something with teacher data ('queryset' holds those data)
else:
return HttpResponse("teacher id not found")