How can i group by student id - python

Please i would like anyone to help me out, tryna grouping this student result from the lecturer session so that lecturer can view each student based on the course student submitted i have successfully get a list but the list are not grouped by the student ids
here is the view for lecturer request
class LecturerListOfStudentResult(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
result = LecturerCourse.objects.filter(lecturer=lecturer)
context = {
'question':result,
}
return render(request, 'superadmin/lecturer/list-result-
student.html', context)
Here is the list of all submitted student result view
class ListAllSubmittedAnswerByCourseRegister(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
result = StudentSubmittedAnswer.objects.filter(lecturer=lecturer,
student=int(kwargs['id']))
context = {'question':result}
return render(request, 'superadmin/lecturer/list-all-result-
student.html', context)
here is the detailview for the list which i only get the count record
class LecturerListOfStudentResultDetail(View):
def get(self, request, *args, **kwargs):
student = Students.objects.get(admin=int(kwargs['id']))
result = StudentSubmittedAnswer.objects.filter(student=student)
skipped = StudentSubmittedAnswer.objects.filter(student=student,
right_answer='Not Submitted').count()
attempted = StudentSubmittedAnswer.objects.filter
(student=student).exclude(right_answer='Not Submitted').count()
rightAns=0
percentage=0
for row in result:
if row.question.right_opt == row.right_answer:
rightAns+=1
if len(result) > 0:
percentage=(rightAns*100)/result.count()
return render(request, 'superadmin/lecturer/view-result-
detail.html', {'result': result,'total_skipped':
skipped,'attempted': attempted, 'rightAns': rightAns,
'percentage':percentage})
Here is my url.py
path('lecturer/course/registration',
LecturerCourseRegistration.as_view(), name="lecturer-course-
registration"),
path('list/lecturer/course/registration',
ListLecturerCourseRegistration.as_view(), name="list-lecturer-
course-registration"),
path('list/submitted/course/answer/student/<int:id>/',
ListAllSubmittedAnswerByCourseRegister.as_view(), name="list-all-
submitted-course-question-by-student"),
here is the list of student html
{% for r in question %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ r.course.name }}</td>
<td>{{ r.created_at }}</td>
<td><a href="{% url 'emisapp:list-all-submitted-course-
question-by-student' r.lecturer.admin.id %}">View</a></td>
{% endfor %}
Here is the html view for looping all the exam submitted for each student
{% for row in result %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ row.course.name }}</td>
<td>{{ row.question.question }}</td>
<td>{{ row.question.right_opt }}</td>
{% if row.question.right_opt == row.right_answer %}
<td class="bg-success text-white">{{ row.right_answer }}</td>
{% else %}
<td class="bg-danger text-white">{{ row.right_answer }}</td>
{% endif %}
</tr>
{% endfor %}
Models.py
class StudentSubmittedAnswer(models.Model):
id = models.AutoField(primary_key=True)
course = models.ForeignKey(Courses)
lecturer = models.ForeignKey(Lecturers)
question = models.ForeignKey(QuizQuestion)
student = models.ForeignKey(Students)
right_answer = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, null=True)
Here is my added Models.py
class StudentSubmittedAnswer(models.Model):
id = models.AutoField(primary_key=True)
lecturercourse = models.ForeignKey(LecturerCourse, null=True,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
lecturer = models.ForeignKey(Lecturers, null=True,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
question = models.ForeignKey(QuizQuestion,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
student = models.ForeignKey(Students,
related_name='studentsubmittedanswer', null=True,
on_delete=models.CASCADE)
right_answer = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, null=True)
class Faculty(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
slug = models.SlugField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Department(models.Model):
id = models.AutoField(primary_key=True)
faculty = models.ForeignKey(Faculty, default=None)
name = models.CharField(max_length=255)
slug = models.SlugField(null=True)
short_desc = models.TextField(null=True, blank=True)
class Courses(models.Model):
id = models.AutoField(primary_key=True)
faculty = models.ManyToManyField(Faculty, related_name='courses')
department = models.ManyToManyField(Department)
name = models.CharField(max_length=255)
slug = models.SlugField()
short_desc = models.TextField(blank=True, null=True)
long_desc = models.TextField(blank=True, null=True)
class StudentFaculty(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students, null=True)
studentfaculty = models.ForeignKey('Faculty')
slug = models.SlugField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class StudentDepartment(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students)
studentfaculty = models.ForeignKey(StudentFaculty)
studentdepartment = models.ForeignKey(Department)
slug = models.SlugField(null=True)
class StudentCourses(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students)
studentfaculty = models.ForeignKey(StudentFaculty)
studentdepartment = models.ForeignKey('StudentDepartment')
studentcourse = models.ForeignKey(Courses)
class QuizQuestion(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey(Lecturers)
faculty = models.ForeignKey(LecturerFaculty, null=True)
lecturerdepartment = models.ForeignKey(LecturerDepartment, null=True)
lecturercourse = models.ForeignKey(LecturerCourse)
session = models.ForeignKey(SessionYearModel)
semester = models.ForeignKey(Semester, null=True)
mark = models.IntegerField(null=True)
examtype = models.ForeignKey('ExamType', related_name='quizzes')
question = models.TextField()
opt_1 = models.CharField(max_length=255)
opt_2 = models.CharField(max_length=255)
opt_3 = models.CharField(max_length=255)
opt_4 = models.CharField(max_length=255)
class LecturerFaculty(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers',
related_name='lecturerfaculty', null=True, on_delete=models.CASCADE)
faculty = models.ForeignKey('Faculty')
slug = models.SlugField(null=True)
class LecturerDepartment(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers')
lecturerfaculty = models.ForeignKey('LecturerFaculty')
lecturerdepartment = models.ForeignKey('Department')
class LecturerCourse(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers')
faculty = models.ForeignKey('Faculty')
lecturerdepartment = models.ForeignKey('LecturerDepartment')
lecturercourse = models.ForeignKey('Courses')
slug = models.SlugField(null=True)
class Lecturers(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg')
middle_name = models.CharField(max_length=255)

You can use values and annotate to group by student Ids.
class ListAllSubmittedAnswerByCourseRegister(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
=> result = StudentSubmittedAnswer.objects.values('student','lecturer').annotate(answers_count=Count('answers')).filter(lecturer=lecturer,
student=int(kwargs['id'])).order_by()
context = {'question':result}
return render(request, 'superadmin/lecturer/list-all-result-
student.html', context)
I assumed the name of the fields in the model student answers lecturer
Refrence
Django documentation: values(), annotate(), and Count
Django documentation: Aggregation, and in particular the section entitled Interaction with default ordering or order_by()
https://docs.djangoproject.com/en/4.0/topics/db/aggregation/#order-of-annotate-and-values-clauses

Related

django form not saving to database(no error message)

First of all, I apologize for using a translator because I am not familiar with English.
My Views.py
def my_create_view(request):
if "reg" in request.method == 'POST':
first_form = FirstRegForm(request.POST, prefix='firstform')
second_form = SecondRegForm(request.POST, prefix='secondform')
if all([first_form.is_valid(), second_form.is_valid()]):
form = first_form.save(commit=False)
form.created_name = request.user.user_name
form.save()
formm = second_form.save(commit=False)
formm.shop_seq = form
formm.save()
return redirect('someview')
else:
first_form = FirstRegForm(prefix='store')
second_form = SecondRegForm(prefix='input')
return render(request, 'app/template.html', {'first_form': first_form, 'second_form': second_form})
My Models.py
from django.db.models import Max
class My_user(AbstractBaseUser):
shop_seq = models.ForeignKey('My_shop', null=True, blank=True, on_delete=models.SET_NULL, db_column="shop_seq")
user_name = models.CharField(max_length=50)
class My_shop(models.Model):
shop_seq = models.CharField(primary_key=True, editable=False, max_length=5)
shop_name = models.CharField(max_length=20, null=True)
shop_code = models.CharField(max_length=15, null=True, unique=True)
shop_address = models.CharField(max_length=40, null=True)
shop_tel = models.CharField(max_length=20, null=True)
created_name = models.CharField(max_length=100, null=True)
def save(self, **kwargs):
if not self.shop_seq:
max = Rate.objects.aggregate(shop_seq_max=Max('shop_seq'))['shop_seq_max'] + 1
self.shop_seq = "{:05d}".format(max if max is not None else 1)
super().save(*kwargs)
class My_model(models.Model):
model_id = models.BigAutoField(primary_key=True)
my_field = models.CharField(max_length=20, null=True)
some_field = models.CharField(max_length=20, null=True)
shop_seq = models.ForeignKey('My_shop', on_delete=models.SET_NULL, null=True, db_column="shop_seq", related_name="shop_model")
My Forms.py
class FirstRegForm(forms.ModelForm):
class Meta:
model = My_shop
fields = ('shop_name', 'shop_code', 'shop_address', 'shop_tel',)
class SecondRegForm(forms.ModelForm):
class Meta:
model = My_model
fields = ('my_field', 'some_field',)
My Template.py
<form method="post">{% csrf_token %}
{{ first_form.shop_name }}
{{ first_form.shop_code }}
{{ first_form.shop_address }}
{{ first_form.shop_tel }}
{{ second_form.my_field }}
{{ second_form.some_field }}
<input class="btn btn-dark" name="reg" type="submit" value="reg">
</form>
If you submit it in this state, it will not be saved in the db.(no error message)
What's wrong with my code?
This line will always be evaluated to false:
if "reg" in request.method == 'POST'
You should change it to:
if request.method == 'POST':

dictionary not coming in for loop despite correct syntax

I am doing crud project which has models PRoducts,categories,sub categories ,color,size.
I am trying to get a django dropdown using SERIALIZERS and have connect categories and subcategories via foreignkeys
below are the models
class Categories(models.Model):
#made changes to category_name for null and blank
category_name = models.CharField(max_length=10)
category_description = models.CharField(max_length=10)
isactive = models.BooleanField(default=True)
class Products(models.Model):
Categories = models.CharField(max_length=15)
sub_categories = models.CharField(max_length=15)
Colors = models.CharField(max_length=15)
Size = models.CharField(max_length=15)
image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
title = models.CharField(max_length=50)
price = models.CharField(max_length=10)
sku_number = models.CharField(max_length=10)
prod_details = models.CharField(max_length=300)
quantity = models.IntegerField(default=0)
isactive = models.BooleanField(default=True)
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=20)
sub_categories_description = models.CharField(max_length=20)
isactive = models.BooleanField(default=True)
def __str__(self):
return self.categories_name
below is the functions
def insert_sub_categories(request):
if request.method == "POST":
insertsubcategories = {}
insertsubcategories['sub_categories_name']=request.POST.get('sub_categories_name')
insertsubcategories['sub_categories_description']=request.POST.get('sub_categories_description')
form = SUBCategoriesSerializer(data=insertsubcategories)
if form.is_valid():
form.save()
print("hkjk",form.data)
messages.success(request,'Record Updated Successfully...!:)')
print(form.errors)
return redirect('sub_categories:show_sub_categories')
else:
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict,many=True)
hm = {'context': category.data}
print(hm)
# print(form.errors)
return render(request,'polls/insert_sub_categories.html',hm)
else:
category_dict = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(category_dict,many=True)
hm = {'context': category.data}
print(hm)
return render(request,'polls/insert_sub_categories.html',hm)
below is the html
<select name="category_name" id="">
{% for c in hm %}
<option value="{{c.id}}">{{c.category_name}}</option>
{% endfor %}
</select>
below is the image of dropdown on which no option arrives
the drop down still doesnt have any options,where am I going wrong?

How can I show a many-to-many field values in a form?

i wrote a code about music and used Many-To-Many-Field() as genre but when i try to show genres it just shows : Genre['a number']
template:
{% extends 'pages/base.html' %}
{% block content %}
<form>
{% if mdata.image %}
<img src="mdata.image.url" height="500" width="500">
{% endif %}
{% for field in form %}
<p>{{ field.label }} : {{ field.value}}</p>
}
{% endfor %}
</form>
edit
{% endblock %}
models is here:(i didnt know which one u need so pasted both of them)
from django.db import models
from django.contrib.auth.models import User
class Genre(models.Model):
name = models.CharField(unique=True,max_length=20)
def __str__(self):
return self.name.title()
class Mdata(models.Model):
name = models.CharField(max_length=100)
artist = models.CharField(max_length=150)
album = models.CharField(max_length=100)
nation = models.CharField(max_length=100)
duration = models.DecimalField(max_digits=4,decimal_places=2)
released_in = models.DecimalField(max_digits=4,decimal_places=0)
uploaded_at = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to='images/',blank=True,null=True)
audio = models.FileField(upload_to='audios/',null=True,blank=True)
genre = models.ManyToManyField(Genre)
uploader = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name.title()+" by "+self.artist.title()
forms.py:(its just a simple form im using)
[![class MdataForm(ModelForm):
class Meta:
model = Mdata
fields =\[
'name',
'artist',
'album',
'genre',
'nation',
'duration',
'released_in',
'image',
'audio',
]
and here the render :dunno if this is enough
[1]: https://i.stack.imgur.com/T5eK2.png
This could be that you don't have a __str__ method on your Genre model. Add a __str__ method and return the genre name. That would be something like:
def __str__(self):
return self.name
self.name here being the field on your genre model used to specify the name. In the sample image below, I set the custom user to return the username by default, that way anywhere I call a user it will automatically show the name of the genre.
class CustomUser(AbstractUser):
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
email = models.EmailField(_("email address"), unique=True, null=True)
phone_number = PhoneNumberField(unique=True, null=True)
username = models.CharField(max_length=100, unique=True, null=True)
password = models.CharField(_("password"), max_length=128, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "User"
verbose_name_plural = "Users"
def __str__(self):
return self.username

Django unable to iterate prefetch_related objects at template

I'm unable to access my prefetch_related objects at my template, can smb help
views.py
def support(request, pk=None):
...
else:
list_support_tickets = sorted(
chain(
SupportTickets.objects.filter(Q(status=0) | Q(status=1), requester=request.user).prefetch_related('reply_relation'), #Can't iter object
), key=attrgetter('creation_date'), reverse=True
)
paginator = Paginator(list_support_tickets, 10)
page = request.GET.get('page')
support_tickets = paginator.get_page(page)
args = {'support_tickets': support_tickets,
'form': form
}
print(list_support_tickets)
return render(request, template, args)
At my template I do the following:
{% for support_ticket in support_tickets %}
...
{% for reply in support_ticket.reply_relation %}
<span class="font-size-small">We have a query, yeah</span>
{% endfor %}
{% endfor %}
But I'm unable get a query here, error:
TypeError: 'GenericRelatedObjectManager' object is not iterable
models.py
class SupportTicketMessages(models.Model):
content_type = models.ForeignKey(ContentType, limit_choices_to=referential_models, on_delete=models.CASCADE)
object_id = models.CharField(max_length=36)
content_object = GenericForeignKey('content_type', 'object_id')
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='support_ticket_reply_author', verbose_name='Author', blank=True)
reply = models.TextField(verbose_name="Reply Content", max_length=2000)
date = models.DateTimeField(auto_now_add=True, blank=False)
class SupportTickets(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
ticket_id = models.IntegerField(default=ticket_id_generator, unique=True, blank=False, null=False, editable=False)
requester = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
category = models.IntegerField(choices=TICKET_CATEGORY, verbose_name='Ticket Category')
subject = models.CharField(max_length=40)
problem_description = models.TextField(max_length=5000)
status = models.IntegerField(choices=STATUS_OF_TICKET, verbose_name='Ticket Status', default=0)
reply_relation = GenericRelation(SupportTicketMessages, related_query_name='reply_relation')
creation_date = models.DateTimeField(auto_now_add=True, null=True)
Thanks in advance
support_ticket.reply_relation is a manager, not a QuerySet, so you can not iterate over it, you use .all() [Django-doc] to iterate over this:
{% for support_ticket in support_tickets %}
…
{% for reply_relation in support_ticket.reply_relation.all %}
…
{% endfor %}
{% endfor %}

django ListView query_set code abbreviation

The codes are as
models.py
class Firm(models.Model):
name = models.CharField(unique=True, max_length=50, verbose_name="Firma Adı")
slug = models.SlugField(unique=True, editable=False, max_length=50)
class Worksite(models.Model):
firm = models.ForeignKey('Firm', verbose_name='Firma', related_name="worksites", on_delete=models.CASCADE)
name = models.CharField(unique=True, max_length=50, verbose_name="Şantiye Adı")
slug = models.SlugField(unique=True, editable=False, max_length=50)
class Subcontractor(models.Model):
worksite = models.ForeignKey('Worksite', on_delete=models.CASCADE)
firm = models.ForeignKey('Firm', related_name="subcontractors", on_delete=models.CASCADE)
Can the queryset code be written shorter?
views.py
class SubcontractorListView(ListView):
template_name = 'firm/subcontractor_list.html'
context_object_name = "firms"
def get_queryset(self):
ws = self.request.user.firm.worksites.values_list('id', flat=True)
ss = Subcontractor.objects.values_list('firm_id', flat=True).filter(worksite_id__in=ws)
return Firm.objects.filter(id__in=ss)
Do you have different and short solutions?
template
{% for firm in firms %}
<div class="btn btn-outline-secondary text-left button">{{ firm }} </div>
{% endfor %}

Categories

Resources