Getting top 3 most enrolled course by students - django

I am building a website where an instructor can create courses and students can enroll the courses. Is there any way to display top 3 most enrolled courses by students that an instructor has created?
I have tried using .values().annotate().order_by()[] but it seems that i cant display it on template.
models.py
class Enrollment(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
enrollment_date = models.DateField(auto_now_add=True, null = True)
class Course(models.Model):
user = models.ForeignKey(Users, on_delete = models.CASCADE)
media = models.ImageField(upload_to = 'media/course')
title = models.CharField(max_length=300, null = False)
subtitle = models.CharField(max_length=500, null = False)
description = models.TextField(max_length=5000, null = False)
language = models.CharField(max_length=20, null = False, choices=LANGUAGE)
level = models.CharField(max_length=20, null = False, choices=LEVEL)
category = models.CharField(max_length=30, null = False, choices=CATEGORY)
subcategory = models.CharField(max_length=20, null = False)
price = models.FloatField(null = True)
roles_responsibilities = models.TextField(max_length=2500, null = False)
timeline_budget = models.TextField(max_length=250, null = False)
req_prerequisite = models.TextField(max_length=2500, null = False)
certificate = models.CharField(max_length=5, null = False, choices=CERTIFICATE)
slug = AutoSlugField(populate_from='title', max_length=500, unique=True, null=True)
views.py
def instructorDashboard(request):
student = Enrollment.objects.filter(course__in=course)
popular_courses= student.values('course__title').annotate(count=Count('course__title')).order_by('-count')[:3]
print(popular_courses)
context = {
'popular_courses': popular_courses,
}
return render(request, 'instructor_dashboard/index.html', context)
index.html
<!-- Popular Courses -->
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Popular Courses</h6>
</div>
{% for popular_course in popular_courses %}
<div class="card-body">
{{ course.title }}
</div>
{% endfor %}
</div>
</div>

Expected: Get the list of courses having more enrollments.
In Django, if we are using ForeignKey, you can easily get all the rows(Enrollment) that are in a relationship with a single row(Course) using the 'realted_name' parameter.
models.py
class Enrollment(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='enrollment')
enrollment_date = models.DateField(auto_now_add=True, null = True)
views.py
# Get the user object and filter the course that are created by user.
# Retrieve all the enrollments for every course created by user and sort in descending order.
# courses_list will be having all the courses that are created by the user.
courses_ranking = []
for course in courses_list:
courses_ranking.append({'course_id': course.id, 'count':course.enrollment.count()})
# After this, courses_ranking will be having list of dict objects that contains courses_id and specific enrollment count. If you sort that dictionary based on the "count" key, you will get the required sorted list.
result = sorted(courses_ranking, key=lambda x: x[1], reverse=True)
# result will have list of courses with highest to lowest enrollments(descending order).

Related

Get product color in color filter by Category wise

I am trying to get a specific category products by category slug.I have Color model,Product model and product variation model in shop app.
class Colour(models.Model):
title = models.CharField(max_length=100)
color_code = models.CharField(max_length=50,null=True)
class Product(models.Model):
product_name = models.CharField(max_length=100,unique=True)
slug = models.SlugField(max_length=100,unique=True)
content = RichTextUploadingField()
price = models.IntegerField()
images = models.ImageField(upload_to='photos/products')
is_available = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE,related_name="procat")
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now=True)
is_featured = models.BooleanField()
class ProductVaraiant(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
color = models.ForeignKey(Colour,on_delete=models.CASCADE,blank=True, null=True)
size = models.ForeignKey(Size, on_delete=models.CASCADE,blank=True, null=True)
brand = models.ForeignKey(Brand,on_delete=models.CASCADE,blank=True, null=True)
amount_in_stock = models.IntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=['product', 'color', 'size','brand'],
name='unique_prod_color_size_combo'
In my views.py,
def shop(request,category_slug=None):
categories = None
products = None
if category_slug != None:
categories = get_object_or_404(Category,slug = category_slug)
products = Product.objects.filter(category=categories,is_available=True).order_by('id')
variation = ProductVaraiant.objects.filter(product__category = categories)
print(variation)
# color = color.objects.all()
products_count = products.count()
else:
products = Product.objects.all().filter(is_available=True).order_by('id')
products_count = products.count()
variation = ProductVaraiant.objects.all()
print(variation)
context = {
'products' : products,
'products_count' : products_count,
'variation' : variation
}
return render(request,'shop/shop.html',context)
my category model,
class Category(MPTTModel):
parent = TreeForeignKey('self',blank=True,null=True,related_name='children',on_delete=models.CASCADE)
category_name = models.CharField(max_length=200,unique=True)
category_img = models.ImageField(upload_to='photos/categories',blank=True)
slug = models.SlugField(max_length=100,unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def img_preview(self):
return mark_safe('<img src = "{url}" width = "50" height = "50"/>'.format(
url = self.category_img.url
))
def __str__(self):
return self.category_name
class Meta:
verbose_name_plural = 'categories'
class MPTTMeta:
order_insertion_by = ['category_name']
what i am trying to get is like i have 3 child category..Each category will have product of any color.So,if i filter product by category,color will be shown in sidebar of that category products without avoid getting duplicates as many product may have same color.So,i am getting same color multiple times.If i need to use distinct(),how to use it in query that will remove duplicate color based on product category.I tried this in template
<form>
<div class="custom-control custom-checkbox d-flex align-items-center justify-content-between mb-3">
<input type="checkbox" class="custom-control-input" checked id="color-all">
<label class="custom-control-label" for="price-all">All Color</label>
<span class="badge border font-weight-normal">1000</span>
</div>
{% for i in variation %}
{% ifchanged i.color %}
<div class="custom-control custom-checkbox d-flex align-items-center justify-content-between mb-3">
<input type="checkbox" class="custom-control-input filter-checkbox" id="{{i.color.id}}" data-filter="color">
<label class="custom-control-label" for="{{i.color.id}}">{{i.color}}</label>
<span class="badge border font-weight-normal">150</span>
</div>
{% endifchanged %}
{% endfor %}
</form>
But,it just remove duplicate of last iteration.How to avoid getting duplicates for all color?
Just where you have a line
# color = color.objects.all()
change it to color = variation.color.all().distinct('id') and then pass it to your template.
Answer of my problem,
what i did:
variation = ProductVaraiant.objects.filter(product__category = categories)
what i changed:
variation = ProductVaraiant.objects.filter(product__category=categories).values('color__title').distinct()
if using postgre database,don't need to use values,just use distinct('color') and you will need to use values for default database to avoid error below,
DISTINCT ON fields is not supported by this database backend

How to filter form based on foreign key?

How can I filter fields in my TopForm in such a way that when a user selects a teacher, automatically all other fields show related values to the teacher. Suppose Adam is the teacher and in the Network department teaches network programming in the 4th semester(added in the admin). Now the user selects Adam, when Adam selected, the department dropdown shows only Network which is related to Adam and so on.
forms.py
class AnswerForm(ModelForm):
class Meta:
model = Student_Answer
fields = ('answer',)
labels = {'answer': ''}
widgets = { 'answer': RadioSelect(choices=RATING_CHOICES)}
class TopForm(forms.Form):
teacher = forms.ModelChoiceField(queryset=Teacher.objects.all())
department = forms.ModelChoiceField(queryset=Department.objects.all())
subject = forms.ModelChoiceField(queryset=Subject.objects.all())
semester = forms.ModelChoiceField(queryset=Semester.objects.all())
models.py
class Question(models.Model):
question = models.CharField(max_length=200)
class Department(models.Model):
name = models.CharField(max_length=60)
class Semester(models.Model):
num = models.IntegerField(choices=SEMESTER, default=1)
class Subject(models.Model):
name = models.CharField(max_length=100)
code = models.CharField(max_length=5, null=True)
semester = models.ForeignKey(Semester, on_delete=models.CASCADE, null=True)
department = models.ManyToManyField(Department)
class Teacher(models.Model):
name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200, null=True)
department = models.ManyToManyField(Department)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
class Student_Answer(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
semester = models.ForeignKey(Semester, on_delete=models.CASCADE)
answer = models.SmallIntegerField(choices=RATING_CHOICES, default=None)
you can do this using js with an api. Example for api, graphene_django or django-rest-framework. And use VueJS on your template. When user selects a teacher you send get request to your api. Your api's response data becomes item for other select box. For example code:
in template.html
<div class="form-row">
<div class="col-md-12" style="padding-left:3px;">
<label for="id_faculty">Teachers</label>
<v-select :options="your_teachers" #input="selectTeacher($event)" label="name" v-model="selected_teacher"></v-select>
</div>
</div>
<!-- Your deparments div begin --!>
<div class="form-row">
<div class="col-md-12" style="padding-left:3px;">
<label for="id_faculty">Deparments</label>
<v-select :options="departments" label="name" v-model="sselected_teacher_departments"></v-select>
</div>
</div>
when select a teacher your element run this function:
getDepartment(){
axios.get(url+'/api/?query={allDepartment{id, name}}').then((response) =>{
this.department = response.data.data.allDepartment;
this.loading = false;
}).catch((error) => {
console.log(error, 'for : getDepartment() function')
});
},

Relating Two Tables together in Django Template and Count the Numbers of Entry

I have two Models in my application that are related to each other (Item and ItemGallery). In my Template, I want the user to have the option of Edit Gallery or Add Gallery. Once the User has entered the image gallery belong to an item before the Interface should change to Edit Gallery. If not, the Interface should be Add Gallery. In a short world, I should be able to know if an item has or have a gallery image or not. If it has gallery then, edit Gallery if not Add Gallery
{% if mylists.itemgallery.all >= 1 %}
<a href="{% url 'add_gallery' mylists.id %}">
<i class="fa fa-pencil"></i>Edit Gallery
</a>
{% else %}
<a href="{% url 'add_gallery' mylists.id %}">
<i class="fa fa-pencil"></i>Add Gallery
</a>
{% endif %}
models.py
class Item(models.Model):
STATUS = (
('Used', "Used"),
('New', "New"),
('Fairly Used', 'Fairly Used'),
('Tokunbo', 'Tokunbo'),
)
ITEM_TYPE = (
('Demand', "Demand"),
('Offer', "Offer"),
)
SALES_TYPE = (
('By Dealer', "By Dealer"),
('By Owner', "By Owner"),
)
CAR_MAKE = (
('Toyota', "Toyota"),
('Nissan', "Nissan"),
('Audi', 'Audi'),
('Honda', 'Honda'),
('Volkswagen', 'Volkswagen'),
('Mercedes Benz', 'Mercedes Benz'),
('Land Rover', 'Land Rover'),
('BMW', 'BMW'),
)
QUALIFICATION = (
('PhD', "PhD"),
('BSc', "BSc"),
('HND', "HND"),
("O'Level", "O'level"),
)
name = models.CharField('Add Title', max_length=100)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
description = models.TextField('Full Detail of the Add')
role = models.TextField('Job Role Detail')
image = models.ImageField(upload_to='item')
status = models.CharField(max_length=50, choices=STATUS, null=True, blank=True)
item_type = models.CharField('Type of Item', max_length=20, choices=ITEM_TYPE, null=True, blank=True)
compensation = models.DecimalField("Conpensation", default='000.00', max_digits=10, decimal_places=2, null=True, blank=True)
price = models.DecimalField("Asking Price", default='000.00', max_digits=10, decimal_places=2, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse('item_details', kwargs={'pk': self.pk})
def __str__(self):
return f'{self.name} - {self.user.email}'
class ItemGallery(models.Model):
item = models.ForeignKey(Item, related_name='itemgallery', on_delete=models.CASCADE)
image = models.ImageField(upload_to='gallery')
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.item.name} - {self.image}'

Queries over ManyToManyField with variable set in a sessions user

Here is my models:
class Clients(models.Model):
client_name = models.CharField(max_lenght=100)
commentaire_clients = models.TextField(blank=False)
date_demande = models.TimeField(auto_now_add=True)
choix = models.ManyToManyField('Agence', blank=True)
def __unicode__(self):
return unicode(self.date_demande)
class Market(models.Model):
nom_market = models.CharField(max_length=200)
code_postal_market = models.ManyToManyField('Lieux', blank=True)
statut_vip = models.BooleanField(default=False)
def __unicode__(self):
return self.nom_market
class Lieux(models.Model):
code_postal = models.CharField(max_length=200)
ville = models.CharField(max_length=200)
region = models.CharField(max_length=200)
departement = models.CharField(max_length=200)
longitude = models.DecimalField(max_digits=9, decimal_places=6)
latitude = models.DecimalField(max_digits=9, decimal_places=6)
pays = models.CharField(max_length=100)
def __unicode__(self):
return unicode(self.code_postal)
Here is my view:
def comparelist(request):
if request.session.get('code_postal'):
poste = request.session.get('code_postal')
else:
poste = "RATE"
market_match = Market.objects.filter(statut_vip=False, code_postal_market = poste)
market_match_vip = Market.objects.filter(statut_vip=True)
#edit bis repetita Market replace Agence models
return render_to_response('compare.html', {
'code_postale': poste,
'bien_immobilier': bien,
'listing_agence' : market_match ,
'listing_vip' : market_match_vip ,
})
What I am trying to do is to make a query that will give me all the market that match:
- statut_vip = False
- code_postal_market = poste (that I obtain from user session from a form on the previous page
then I try to render it in my templates via:
{% for mes_market in listing_vip %}
<br>{{mes_market.nom_market}}
<br>{{mes_market.statut_vip}}
{% endfor %}
edit
here is my template for listing_agence (same as the previous one but with the right reference) sorry for the error.
{% for mes_agences in listing_agence %}
<br>{{mes_agences.nom_market}}
<br>{{mes_agences.statut_vip}}
{% endfor %}
My second queries to list all VIP clients do work but when I try to filter via the postal code given by the user via a form (and keeping the record via sessions)
nothing appears.
Thank you for your help!
I finally made it!
I replaced:
market_match = Market.objects.filter(statut_vip=False, code_postal_market = poste)
by
market_match = Market.objects.filter(statut_vip=False, code_postal_market__code_postal=poste)
code_postal is from the table Lieux

Django forms breaking in IE7

I've got a dJango webform from a model with some error checking (valid email field,etc).
Everything works fine in various browsers Opera,Camino,Netscape,Safari and IE (except IE7).
All I get in IE7 is the 'Internet Explorer cannot display the webpage' message. If the forms valid the data gets written to the database so I think its something to do with the redirect stage.
I've tried various things method=get and javascript form submission but nothing seems to stop IE7 giving me this error.
Any help would be appreciated.
forms.py
class NewElectiveForm(ModelForm):
host_country = forms.CharField(widget=forms.widgets.Select(choices=COUNTRIES) , label="Destination")
host_type = forms.CharField(widget=forms.widgets.Select(choices=HOST_TYPE) , label="Location type")
host_name = forms.CharField(max_length=256, label="Name of host institution")
host_street = forms.CharField(required = False, max_length=100, label="Street")
host_city = forms.CharField(required = False, max_length=100, label="City")
host_district = forms.CharField(required = False, max_length=100, label="District")
host_zipcode = forms.CharField(required = False, max_length=100, label="Zipcode")
host_supervisor = forms.CharField(required = False, max_length=256, label="Name of supervisor")
host_email = forms.EmailField(required = False, max_length=100, label="Email")
host_fax = forms.CharField(required = False, max_length=100, label="Fax.No.")
host_tel = forms.CharField(required = False, max_length=100, label="Tel.No.")
start_date = forms.DateField(widget=SelectDateWidget(),label="Elective start date")
end_date = forms.DateField(widget=SelectDateWidget(),label="Elective end date")
subject = forms.CharField(required = False, max_length=256,label="Subject")
reasons = forms.CharField(required = False, widget=forms.widgets.Textarea(attrs={'class':'question'}), label="Please state briefly the reasons for this choice's location and subject")
outcomes = forms.CharField(required = False, widget=forms.widgets.Textarea(attrs={'class':'question'}), label="Please give upto to 4 outcomes that you hope to achieve during this elective")
your_mobile = forms.CharField(required = False, max_length=100, label="Please provide your mobile number if you are taking it with you")
insurance = forms.BooleanField(required = False, label="Please confirm that you have arranged holiday insurance")
malpractice = forms.BooleanField(required = False, label="Please confirm that you have medical malpractice cover")
groupinfo = forms.CharField(required = False, label="If you planning your Elective in a group, please list your fellow students")
#risk_upload = forms.FileField(widget=AdminFileWidget, required = False, label='Upload a completed risk assesment form')
#evidence_upload = forms.FileField(widget=AdminFileWidget, required = False, label='Upload an evidence document')
class Meta:
model = ElectiveRecord
exclude = ('id', 'review','elective', 'status', 'edit_userid','modified')
html template:
<form enctype="multipart/form-data" method="post" class="uniForm" id="newform" >
{% for i in form %}
<div class="fieldwrapper {% for error in i.errors %} error {% endfor %}">
{% for error in i.errors %}
<b>{{error|escape}}</b><br/>
{% endfor %}
{{ i.label_tag }} :
{% if i.html_name == "reasons" or i.html_name == "outcomes" %} <br/> {% endif %}
{{ i }}
{% if i.html_name == "evidence_upload" %} <br/>latest file= xxx {% endif %}
{% if i.html_name == "risk_upload" %} <br/>latest file= xxx {% endif %}
</div>
{%endfor%}
<div class="fieldWrapper"> <input type="submit" value="Save" NAME='save' > </div>
</form>
models.py
class ElectiveRecord(models.Model):
elective = models.ForeignKey(Elective, null=True, blank=True)
status = models.CharField(choices=ELECTIVE_STATUS_FLAGS, max_length=40)
edit_date = models.DateTimeField(auto_now_add=True)
edit_userid = models.CharField(max_length=12)
host_country = models.CharField(max_length=100, help_text="Destination")
host_type = models.CharField(choices=HOST_TYPE, max_length=10, help_text="Location type")
host_name = models.CharField(max_length=256, help_text="Name of host institution")
host_street = models.CharField(max_length=100, help_text="Street")
host_city = models.CharField(max_length=100, help_text="City")
host_district = models.CharField(max_length=100, help_text="District")
host_zipcode = models.CharField(max_length=100, help_text="Zipcode")
host_supervisor = models.CharField(max_length=256, help_text="Name of supervisor")
host_email = models.CharField(max_length=100, help_text="Email")
host_fax = models.CharField(max_length=100, blank=True, help_text="Fax.No.")
host_tel = models.CharField(max_length=100, help_text="Tel.No.")
start_date = models.DateField(help_text="Elective start date")
end_date = models.DateField(help_text="Elective end date")
subject = models.CharField(max_length=256,help_text="Tel.No.")
reasons = models.TextField(help_text="Please state briefly the reasons for this choice's location and subject")
outcomes = models.TextField(help_text="Please give upto to 4 outcomes that you hope to achieve during this elective")
your_mobile = models.CharField(max_length=100, blank=True, help_text="Please provide your mobile number if you are taking it with you")
insurance = models.BooleanField(default=False, help_text="Please confirm that you have arranged holiday insurance")
malpractice = models.BooleanField(default=False, help_text="Please confirm that you have medical malpractice cover")
groupinfo = models.CharField(max_length=256, blank=True, help_text="If you planning your Elective in a group, please list your fellow students")
modified = models.DateTimeField(auto_now_add=True)
class Meta:
get_latest_by = 'modified'
def __unicode__(self):
return u"[%s] %s, %s " % (self.id,self.host_name,self.subject)
Confirm that it's the redirect stage that's causing the problem by replacing
HttpResponseRedirect(url)
with
HttpResponse('<!DOCTYPE html><html><head><title>title</title></head><body>%(url)s</body></html>' % {'url':url})
If this doesn't render, then the problem is happening before the redirect. If it does render, then the problem may be the redirect, or it may be the redirected page. Click on the link. If the next page displays correctly, the problem is almost certainly the redirect itself. Otherwise, the problem is in the redirected page.