I have django course model and custom user as students
I added some course for logged student, Now i need to show the profile of user or student and his course in student_profile.html
here is my model for course
class Course(models.Model):
students = models.ManyToManyField('Profile', blank=True)
Course_Name = models.CharField(max_length=200)
Duration_Time = models.CharField(max_length=50)
Course_Fee = models.IntegerField()
Discount_Fee = models.IntegerField()
Course_Image = models.FileField()
Course_Description = models.TextField(max_length=500)
def __str__(self):
return self.Course_Name + ' - ' + self.Duration_Time
here is model profile
class Profile(models.Model):
STUDENT = 1
TEACHER = 2
ROLE_CHOICES = (
(STUDENT, 'Student'),
(TEACHER, 'Teacher'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=30, blank=False, help_text='Required.')
email_confirmed = models.BooleanField(default=False)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
# this method called for admin panel
class Meta:
verbose_name = 'profile'
verbose_name_plural = 'profiles'
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
here is my students profile template
{% if user.is_authenticated %}
<p>welcome {{ user.first_name }} --
{% for course in user.profile.course_set.all %}
{{ course.name }}{% if not forloop.last %},{% endif %}
{% empty %}
<span>No course</span>
{% endfor %}
</p>
{% endif %}
<p>Logout</p>
When student login in profile template showing only studentname
Here is result in browser
welcome studnet for course -- ,
Logout
You can add a ManyToManyField in your Course Model, named:
class Course(models.Model):
# other fields
students = models.ManyToManyField('Profile',blank=True)`
So when you have a profile instance, this query profile_instance.course_set.all() will display all the courses that this profile/student has attended
In your view, don't override get_queryset()
{% if user.is_authenticated %}
<p>welcome {{ user.first_name }} --
{% for course in user.profile.course_set.all %}
{{ course.Course_Name }}{% if not forloop.last %},{% endif %}
{% empty %}
<span>No course</span>
{% endfor %}
</p>
{% endif %}
<p>Logout</p>
...
Related
I wanted to ask you for your help. I have two models. In the first one I wanted to reference foriegn key from the second one to be able to print votescore that I store there.
My models.py :
class Question(models.Model):
question = models.CharField(max_length=300)
answered = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
datecompleted = models.DateTimeField(null=True, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
votesscore = models.ForeignKey('VoteQuestion', on_delete=models.CASCADE, null=True, blank=True, related_name='question_votesscore')
def __str__(self):
return self.question
class VoteQuestion(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE, blank=False, null=True)
votesubmitted = models.DateTimeField(null=True, blank=True)
votesscore = models.IntegerField(default='0')
amountofvotes = models.IntegerField(default='0')
def __str__(self):
return self.votesscore
class Meta:
unique_together = ['user', 'question', 'votesscore']
Next in my views.py:
def home(request):
allquestionswithanswers = Question.objects.filter(datecompleted__isnull=False)
allquestionswithoutanswers = Question.objects.filter(datecompleted__isnull=True)
return render(request, 'main/home.html', {'allquestionswithanswers': allquestionswithanswers, 'allquestionswithoutanswers': allquestionswithoutanswers})
And in my home.html I am calling it like this:
{% for question in allquestionswithanswers %}
<li>
{{ question }} Score: {{ question.votesscore }} {{ question.user }}
<br><br>
<form class='my-ajax-form' method='POST' action='' data-url="{% url 'questionvoteup' question.id %}" >
{% csrf_token %}
<button type='submit'>UP</button>
</form>
{% for answer in question.answer_set.all %}
{{ answer }}<br>
{% endfor %}
</li>
{% endfor %}
And when I try to print {{ question.votesscore }} I get value "None". Yet I am sure that in database it is an integer value. Could you please point me in right direction with this ?
Thanks and Cheers
I'm trying to loop over my FeatureCatergories, FeatureSubcategories and Features. I'm able to loop over my feature categories just fine. Now I want to loop over my feature subcategories and finally features. I'm not sure what to call in my template for subcategories.. Should it be {{featuresubcategory.title}}? What about features?
views.py
def features_view(request):
context = {
"feature_categories": FeatureCategory.objects.prefetch_related('featuresubcategory_set').all(),
}
return render(request=request, template_name="main/features.html", context=context)
template.html
{% for category in feature_categories %}
{{category.title}}
{% for subcategory in featuresubcategory %}
{{ subcategory.title }}
{% endfor %}
{% endfor %}
models.py
class FeatureCategory(models.Model):
title = models.CharField(max_length=50)
featured_image = models.ImageField(blank=True, upload_to="features/")
category_slug = AutoSlugField(null=True, default=None,
unique=True, populate_from='title')
class Meta:
verbose_name_plural = "Feature Categories"
def __str__(self):
return self.title
class FeatureSubcategory(models.Model):
title = models.CharField(max_length=50)
category = models.ForeignKey('FeatureCategory', on_delete=models.CASCADE)
category_slug = AutoSlugField(null=True, default=None,
unique=True, populate_from='title')
class Meta:
verbose_name_plural = "Feature Subcategories"
def __str__(self):
return self.title
class Feature(models.Model):
title = models.CharField(max_length=150)
category = models.ManyToManyField(FeatureSubcategory)
description = models.TextField()
featured_image = models.ImageField(upload_to=image_dir)
class Meta:
verbose_name_plural = "Features"
def __str__(self):
return self.title
In your template, you must change
featuresubcategory with category.featuresubcategory_set.all()
also,
use prefetch_related('featuresubcategory') instead of prefetch_related('featuresubcategory_set')
{% for category in feature_categories %}
{{category.title}}
{% for subcategory in category.featuresubcategory_set.all %}
{{ subcategory.title }}
{% endfor %}
{% endfor %}
For features of subcategory, add related_name to your category field
category = models.ManyToManyField(FeatureSubcategory,related_name='subcategory_features')
and now, you can use it in your template, and don't forget to make migrate
{% for category in feature_categories %}
{{category.title}}
{% for subcategory in category.featuresubcategory_set.all %}
{{ subcategory.title }}
{% for feature in subcategory.subcategory_features.all %}
{{feature.title}}
{% endfor %}
{% endfor %}
{% endfor %}
You can see related objects reference here
I have a list that is generated by a method on one of my models. On the home page it works wonderfully, however when I go to a detail view of one project I can access all the parts of that project as they are direct fields of the Model, but I can't access the items in the list.
Model:
class Project(models.Model):
date_published = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
area = models.ForeignKey(Area, on_delete=models.PROTECT)
title = models.CharField(max_length=128, unique=True)
slug = models.SlugField(max_length=64)
summary = models.CharField(max_length=256)
others = models.CharField(max_length=128, blank=True)
deadline = models.DateField(null=True, blank=True)
priority = models.ForeignKey(Priority, on_delete=models.PROTECT)
closed = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.title)
super(Project, self).save(*args, **kwargs)
#property
def updates(self):
updates = []
sequence_id = 1
categories = set(self.update_set.all().values_list(
'category__id', flat=True))
for cat_id in categories:
a = Update.objects.filter(
project=self, category__id=cat_id).order_by('added').last()
if cat_id == sequence_id:
updates.append(a)
else:
for i in range(cat_id - sequence_id):
updates.append('null')
updates.append(a)
sequence_id = cat_id
sequence_id += 1
return updates
class Update(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
category = models.ForeignKey(UpdateCategory, on_delete=models.PROTECT)
update = models.TextField(max_length=240, blank=True)
added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.update
The view is simple:
class ProjectDetailView(DetailView):
template_name = 'project_portal/project_detail.html'
queryset = Project.objects.all()
and here is the dynamic url that I am using:
path('project/<int:pk>/',
ProjectDetailView.as_view(), name='project_detail'),
As for the template, I'm lost, here is one of the things I have tried:
<!DOCTYPE html>
{% extends "project_portal/base.html" %}
{% block home %}
<div id="main">
<div id="content">
<div>
<h1>{{ object.title }}</h1>
<h1>hello</h1>
{% if object_list %}
{% for item in updates %}
<p>{{ item }}</p>
{% endfor %}
{% else %}
<h2>No records found for this project</h2>
{% endif %}
</div>
</div>
</div>
{% endblock %}
What do I need to do to access the "updates" list that gets generated?
update is a property of the model instance, you need to access it from there like any other attribute. Also note, there is no object_list in a detail view.
<div>
<h1>{{ object.title }}</h1>
<h1>hello</h1>
{% for item in object.updates %}
<p>{{ item }}</p>
{% endfor %}
</div>
For each Product I need to show all it's reviews with an attached profilepicture, this requires queries into 3 models but I need a maximum of 2 for loops as when I do the Profile for loop all the images appear together as shown below. Ideally review & profile datasets are put together so only one profilepicture appears for each review.
Is there a way to fix this issue?
models.py
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='products/default_product.jpg', upload_to='products')
class Review(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
profilephoto = models.ImageField(default='profiles/default_profile.jpg', upload_to='profiles')
views.py
class ProductDetailView(TemplateView):
# template_name = 'reviewApp/test.html'
template_name = 'reviewApp/product_detail.html'
def get_context_data(self, **kwargs):
prod = self.kwargs['pk']
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['Products'] = Product.objects.filter(id=prod)
context['Reviews'] = Review.objects.filter(product=prod)
profile_ids = Review.objects.filter(product=prod).values_list('profile_id', flat=True)
context['Profiles'] = Profile.objects.filter(id__in=profile_ids)
return context
product.html
{% for prod in Products %}
<img src="{{prod.productphoto.url}}">
{{ prod.brand }} {{ prod.name }}
£{{ prod.cost }}
{{ prod.category }}
{{ prod.releasedate }}
{{ prod.description }}
{% endfor %}
{% for rev in Reviews %}
{% for prof in Profiles %}
<img src="{{prof.profilephoto.url }}">
{% endfor %}
{{ rev.rating }}
{{ rev.author }}
{{ rev.reviewtext }}
{% endfor %}
view
You can query the profile picture as rev.profile.profilephoto
I have a this models
class Project(models.Model):
name = models.CharField(max_length=20)
description = models.CharField(max_length=200, null=True, blank=True)
creation_date = models.DateTimeField(auto_now_add=True, auto_now=False)
group_owner = models.ForeignKey(User)
def __str__(self, y):
return smart_str(self.name)
class Note(models.Model):
title = models.CharField(max_length=50, null=True, blank=True)
content = models.CharField(max_length=1000)
creation_date = models.DateTimeField(auto_now_add=True, auto_now=False)
updated_date = models.DateTimeField(auto_now_add=False, auto_now=True)
projectId = models.ForeignKey(Project, on_delete=models.CASCADE)
userid = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return smart_str(self.title)
which i would like to join them in one view, which would be shown when someone enters to this url http://localhost.com:8000/project/ID.
obviously the ID will depend in Project.id and it will have to get all the Notes that are related to it.
Meanwhile my views.py looks like this
class ProjectDetail(generic.DetailView):
model = Project
template_name = 'scribere/project/detail.html'
def get_queryset(self):
return Project.objects.filter(group_owner__exact=self.request.user.id)
class ProjectNoteList(generic.ListView):
context_object_name = 'project_note_list'
template_name = 'scribere/note/index.html'
def get_queryset(self):
return Note.objects.filter(userid__exact=self.request.user.id, projectId__exact=self.kwargs['pk'])
and the template
{% extends "base/adminsNavBar.html" %}
{% load i18n %}
{% block head_title %}{% trans 'Projects Details' %}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumb"><p>{% trans 'Project Details' %}</p></div>
{% endblock %}
{% block content %}
<div class='row'>
{% trans 'Back' %}
{% trans 'Notes' %}
</div>
<div>
{{project.name}}
</div>
<div class = "note-list">
<ul>
{% for note in project_note_list %}
<li>
{{note}}
</li>
{% endfor %}
</ul>
</div>
{% endblock %}
which doesn't load any information about the note. What am i missing?
Unless you are populating project_note_list with some information, there will be nothing to iterate over.
By virtue of the ForeignKeys, and having a Many to one relation the project object will have a set of notes associated with it, without having to look them up.
You should be able to query them using project.note_set.all() or in your template by using:
{% for note in project.note_set %}