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 %}
Related
Currently im working on an Ecommerce project in Django where i have a Order model which has Foreign key relation with Product. So all the product details are fetched from product model. Now im facing issue with the same. Whenever I make any change to Product object its getting updated in all the related Order objects too even for orders placed in past.
Is it possible to keep past order's product values unchanged whenever Product object is updated in future? Please help. Below are the codes for your reference.
Product Model
class Product(models.Model):
measurement_choices = (('Liter', 'Liter'), ('Kilogram', 'Kilogram'), ('Cloth', 'Cloth'),
('Shoe', 'Shoe'))
name = models.CharField(max_length=200)
sku = models.CharField(max_length=30, null=True)
stock = models.CharField(max_length=10, null=True)
measurement = models.CharField(choices=measurement_choices, max_length=20, null=True)
description = models.CharField(max_length=10000)
price = models.DecimalField(max_digits=7, decimal_places=2)
discounted_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
image = models.ImageField(upload_to='product/images', default='product.png', null=True,
blank=True)
image_one = models.ImageField(upload_to='product/images', null=True, blank=True)
image_two = models.ImageField(upload_to='product/images', null=True, blank=True)
image_three = models.ImageField(upload_to='product/images', null=True, blank=True)
image_four = models.ImageField(upload_to='product/images', null=True, blank=True)
image_five = models.ImageField(upload_to='product/images', null=True, blank=True)
tags = models.ManyToManyField(Tags)
category = models.ForeignKey(Category,on_delete=models.SET_NULL,null=True,blank=True)
sub_category = models.ForeignKey(SubCategory, on_delete=models.SET_NULL,
null=True,related_name='+')
status = models.CharField(max_length=20, choices=(('Active', 'Active'), ('Inactive',
'Inactive')))
brand = models.ForeignKey(Brand,on_delete=models.PROTECT,blank=True, null=True)
offer = models.ForeignKey(Offer, on_delete=models.CASCADE, null=True, blank=True)
color = models.ForeignKey(Color , blank=True, null=True , on_delete=models.PROTECT)
size_type = models.ForeignKey(Size , blank=True, null=True , on_delete=models.PROTECT)
history = HistoricalRecords()
Order Model
class Order(models.Model):
order_status = (('Pending', 'Pending'), ('Under Process', 'Under Process'), ('Dispatched',
'Dispatched'),
('Delivered', 'Delivered'), ('Cancelled', 'Cancelled'), ('Out for delivery',
'Out for delivery'))
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
shipping_address = models.ForeignKey(ShippingAddress, on_delete=models.DO_NOTHING, null=True,
blank=True)
order_created = models.DateTimeField(auto_now_add=True,null=True)
date_ordered = models.DateTimeField(null=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
order_number = models.CharField(max_length=20, unique=True, null=True)
status = models.CharField(choices=order_status, default='Pending', max_length=30)
payment_status = models.CharField(choices=(('Received', 'Received'), ('Failed', 'Failed'),
('Pending', 'Pending')),
default='Pending', max_length=30)
ip_address = models.CharField(max_length=30, null=True)
# Payment details captured from payment gateway
payment_order_id = models.CharField(max_length=100, null=True) # razorpay order id
payment_id = models.CharField(max_length=100, null=True) # Razorpay payment id
payment_signature = models.CharField(max_length=100, null=True)# razorpay paymnet signature
payment_method = models.CharField(max_length=100, null=True)
history = HistoricalRecords()
I think there are a few options for you here if I understand your question correctly.
Either you can serialize the actual product details when saving the order. This could be done by using Django serialization and then storing this serialized product on the order with a JSONField. This way you'll keep the state for a product if you want to display or use the data later.
Another way would be to store a new product with a version ID, instead of updating your old products. This could be done by hooking on the pre save, creating a new version and blocking the saving of the old model. This way you'll store and can reuse the model in your templates. https://docs.djangoproject.com/en/3.2/topics/signals/
The last idea would be to use a historical model insert, such as django-simple-history. This would handle changes and updates for you, but you'll have to relate to a given history instance.
I have a Django website and part of it lists data in rows with the primary key in one of the columns. This works great except for when I have separate users. I'm using foreign keys in each model to separate the different user's data. My problem is that the data for each user has to have a number in the column that increments numerically and does not have any spacing, for instance, 1,2,3,5 is bad. If User1 is uploading data and halfway through User2 uploads a row of data then if I use the primary key the numbers will not be in numerical order for each user and will read 1,2,3,5 for User1 and 4 for User2. I tried forloop counter but I need the numbers all the be assigned to the row and not change if one is deleted. Ive been at this for 2 weeks and am having a really hard time describing my problem. I think I need somesort of Custom User Primary Key, a primary key for each user. Any help at this point is greatly appreciated, Thanks!
I finally figured it out after about a week.
models.py:
class Sheet_Building(models.Model):
user = models.ForeignKey(User, default=True, related_name="Building", on_delete=models.PROTECT)
count_building = models.IntegerField(blank=True, null=True)
date = models.DateField(blank=True, null=True, verbose_name='Inspection Date')
time = models.TimeField(blank=True, null=True, verbose_name='Inspection Time')
inspection_type = models.CharField(max_length=16, choices=INSPECTION_TYPE_BI, blank=True, null=True, verbose_name='Inspection Type')
flname = models.CharField(max_length=25, blank=True, null=True, verbose_name='Inspector')
report_date = models.DateField(blank=True, null=True, verbose_name='Report Date')
department = models.CharField(max_length=29, choices=DEPARTMENT_BI, blank=True, null=True, verbose_name='Department')
responsible_name = models.CharField(max_length=25, blank=True, null=True, verbose_name='Responsible Person')
building_address = models.CharField(max_length=52, choices=BUILDING_ADDRESS, blank=True, null=True, verbose_name='Building and Address')
floor = models.CharField(max_length=8, choices=FLOOR_LEVEL_BI, blank=True, null=True, verbose_name='Floor / Level')
room = models.CharField(max_length=35, blank=True, null=True, verbose_name='Area / Room')
location = models.CharField(max_length=10, choices=LOCATION_BI, blank=True, null=True, verbose_name='Location')
priority = models.IntegerField(blank=True, null=True, verbose_name='Priority')
hazard_level = models.CharField(max_length=20, choices=HAZARD_LEVEL_BI, blank=True, null=True, verbose_name='Hazard Level')
concern = models.CharField(max_length=31, choices=CONCERN_BI, blank=True, null=True, verbose_name='Concern')
codes = models.CharField(max_length=51, choices=CODES_BI, blank=True, null=True, verbose_name='Element and Code')
correction = models.TextField(max_length=160, blank=True, null=True, verbose_name='Corrective Action')
image = models.ImageField(blank=True, null=True, verbose_name='Image', upload_to='gallery')
notes = models.TextField(max_length=500, blank=True, null=True, verbose_name="Inspector's note")
class Meta:
ordering = ['-pk']
def __str__(self):
return self.flname or 'None'
def get_absolute_url(self):
return reverse('list_building')
view.py:
def adddata_building(response):
if response.method == 'POST':
form = SheetForm_Building(response.POST, response.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.user = response.user #User
if Sheet_Building.objects.filter(user=response.user).values_list('count_building'):
instance.count_building = Sheet_Building.objects.filter(user=response.user).aggregate(count_building=Max('count_building'))['count_building'] + 1 #Count
else:
instance.count_building = 1
instance.save()
response.user.Building.add(instance)
return redirect('list_building')
else:
form = SheetForm_Building()
return render(response, 'sheets/add_data/add_data_building.html', {'form': form})
HTML:
{% for post in object_list %}
{{ post.count_building }}
{% enfor %}
I am trying to create cart using django but i am getting this error. while I try to check that the user is authenticated or no i used customer = request.user.customer but it says user has no attribute customer
Here is my views.py
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = OrderModel.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
else:
items = []
context = {}
return render(request, 'Home/cart.html', context)
here is my models.py
class CustomerModel(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='')
customer_name = models.CharField(max_length=1000, null=True)
customer_phone = models.CharField(max_length=20, null=True)
def __str__(self):
return self.customer_name
class OrderModel(models.Model):
customer = models.ForeignKey(CustomerModel, on_delete=models.SET_NULL, null=True, blank=True)
order_date = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False,null=True,blank=True)
transaction_id = models.CharField(max_length=1000, null=True)
def __str__(self):
return str(self.id)
class OrderItem(models.Model):
product = models.ForeignKey(ProductModel, on_delete=models.SET_NULL, null=True, blank=True)
order = models.ForeignKey(OrderModel, on_delete=models.SET_NULL, null=True, blank=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
class Address(models.Model):
customer = models.ForeignKey(CustomerModel, on_delete=models.SET_NULL, null=True, blank=True)
order = models.ForeignKey(OrderModel, on_delete=models.SET_NULL, null=True, blank=True)
address = models.CharField(max_length=10000)
city = models.CharField(max_length=1000)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.address
I am stuck here and cant understand what to do.
I think changing the line customer = request.user.customer to customer = request.user.customermodel may solve your problem. If you want to use customer = request.user.customer add related name to your CustomerModel's field:
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='', related_name='customer')
Note: Make sure that your user object has a related profile.
For example add an extra condition to your codes like following:
if hasattr(request.user, 'customer'): # If you have related name otherwise use customermodel
customer = request.user.customer
else:
# Return a proper message here
Because if your user object has no related profile this line of code will raise RelatedObjectDoesNotExist error type.
For the user field of the CustomerModel, you must set "related_name" and "related_query_name" to "customer":
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='', related_name='customer', related_query_name='customer')
You have to set the "related_name" parameter in your CustomerModel customer field for reverse access
user = models.OneToOneField(User, related_name="user", on_delete = models.CASCADE, null=True, blank=True, default='')
if you don't set the related name django will generate field name + "_set" for the access (user_set in your example)
I am currently working on django. I created 4 classes in models.py, one of them is ReactionMeta class. This class has 62 columns, which defined as below:
class Reactionsmeta(models.Model):
id = models.ForeignKey('Reactions', db_column='id', primary_key=True, max_length=255, on_delete=models.CASCADE)
name = models.CharField(max_length=255, blank=True, null=True)
metabolite1 = models.ForeignKey('Metabolites', db_column='metabolite1', blank=True, null=True,
on_delete=models.CASCADE)
stoichiometry1 = models.CharField(max_length=255, blank=True, null=True)
metabolite2 = models.ForeignKey('Metabolites', db_column='metabolite2', blank=True, null=True,
on_delete=models.CASCADE, related_name='+')
stoichiometry2 = models.CharField(max_length=255, blank=True, null=True)
metabolite3 = models.ForeignKey('Metabolites', db_column='metabolite3', blank=True, null=True,
on_delete=models.CASCADE, related_name='+')
stoichiometry3 = models.CharField(max_length=255, blank=True, null=True)
metabolite4 = models.ForeignKey('Metabolites', db_column='metabolite4', blank=True, null=True,
on_delete=models.CASCADE, related_name='+')
#...
Some of the reactions, may have 6 metabolites, however, some of reactions may only have 2 metabolites and stoichiometries, which means there is no value of this reaction in metabolite3,4,5,6...columns and stoichiometry 3,4,5,6...columns.
In that case, how can I only display the Charfield with data while undisplay those Charfield with no value in django-admin?
So I think there is model design issue here. For my case i would have done this as follows
class ReactionMeta(models.Model):
reaction = models.ForeignKey(Reaction, ..)
name = models.CharField(..)
data = models.ForeignKey(Data, ..)
Contructing the Data class to hold the Stoichiometry and Metabolite
class Data(models.Model):
stoichiometry = models.CharField(..)
metabolite = models.ForeignKey(..)
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 %}