Python Django - Count objects based on owner that is the user - python

I have users who listed their textbook.
I need to count objects in Textbook model and display total count in the side menu.
Here is my Model
from django.db import models
from django.http import HttpResponse
from django.urls import reverse
from django.contrib.auth.models import User
from django.utils.functional import cached_property
class Textbooks(models.Model):
owner = models.ForeignKey(User, on_delete=models.PROTECT, null=True, blank=True)
title = models.CharField(max_length=1000)
isbn = models.CharField(max_length=20)
author = models.CharField(max_length=250)
edition = models.CharField(max_length=50)
rrp = models.CharField(max_length=30)
about = models.TextField(max_length=1000, null=True)
textbook_image = models.FileField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse('textbooks:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.title
I used Custom template tag
class CustomTag(template.Node):
def render(self, context):
context['my_custom_tag_context'] = Textbooks.objects.filter(owner=self.user.request).count()
return ''
#register.tag(name='get_custom_tag')
def get_custom_tag(parser, token):
return CustomTag()
enter image description here
AttributeError at /
'CustomTag' object has no attribute 'user'. It seems that i cant use filter in template tag.
is there any other way i can filter them and show the count by owner who is logged in?
Here is what i intend to have.
enter image description here

You have to change below line in...
user = context['request'].user
context['my_custom_tag_context'] = Textbooks.objects.filter(owner=user).count()
instead of
context['my_custom_tag_context'] = Textbooks.objects.filter(owner=self.user.request).count()
You can get user from request.

Related

Django-Extra-Views: Inlines child model gets author none. How do I set it the same as the parent?

I have been spinning my wheels on this issue for a day or two. I have django web application that has 3 models
users/models.py:
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
# Create your models here.
class ExtendedUser(models.Model):
user=models.OneToOneField(User,null=True, on_delete=models.CASCADE)
def full_name(self):
return (self.user.get_full_name())
def __str__(self):
return self.user.get_full_name()
#receiver(post_save, sender=User)
def create_or_update_user_extendeduser(sender, instance, created, **kwargs):
if created:
ExtendedUser.objects.create(user=instance)
instance.extendeduser.save()
playground/models.py:
class Customer(models.Model):
def __str__(self):
return self.Customer_Name
Customer_Name = models.CharField(max_length=100)
SFDC_Customer_Record_Number = models.IntegerField(default='')
Zone = models.CharField(max_length=50, default='')
Government = models.BooleanField(default=False)
date_posted = models.DateTimeField(default=timezone.now)
customerauthor = models.ForeignKey(ExtendedUser, on_delete=models.DO_NOTHING,default=ExtendedUser)
def get_absolute_url(self):
return reverse('playground-home')
class Vue_Quote(models.Model):
def __str__(self):
return self.Quote_Name
Quote_Name = models.CharField(max_length=100)
SFDC_Golden_Opp_ID = models.IntegerField()
Vue_System_Count = models.IntegerField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(ExtendedUser, on_delete=models.DO_NOTHING,default=ExtendedUser,blank=True,null=True)
Quote_Type = models.CharField(max_length=100)
Customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING, default='')
def get_absolute_url(self):
return reverse('quote-detail',kwargs={'pk': self.pk})
I am using the 3rd party application django-extra-views to create a single form which allows a user to create a customer and quote at the same time. Views.py:
class QuoteInline(InlineFormSetFactory):
model = Vue_Quote
fields = ['Quote_Name','SFDC_Golden_Opp_ID','Vue_System_Count','Quote_Type',]
factory_kwargs = {'extra':1}
class CreateQuoteInlinesView(CreateWithInlinesView):
model = Customer
inlines = [QuoteInline]
fields = ['Customer_Name','SFDC_Customer_Record_Number','Zone','Government']
template_name= 'quote_and_customer.html'
def forms_valid(self, form, inlines):
form.instance.customerauthor = ExtendedUser.objects.get(user=self.request.user)
return super().forms_valid(form,inlines)
All of this is working great except for that I am not able to save the author for the Vue_Quote model...I always get "None":
Image of Vue_Quote.author = None from my form
I have tried a wide range of solutions but cannot seem to solve this and I am finding very little documentation on django-extra-views to support my finding a solution.
Any assistance is greatly appreciated!
Welp, I've looked at the source code and tried to figure it out.. It's really abstract and a lot of inheritance
This would be my best guess:
def forms_valid(self, form, inlines):
user = ExtendedUser.objects.get(user=self.request.user)
form.instance.customerauthor = user
for i in inlines:
i.instance.author = user
i.save()
return super().forms_valid(form,inlines)
Or if you wanted to also define the Customer field in this forms_valid you could do it after the super call
You could try something like this:
def forms_valid(self, form, inlines):
user = ExtendedUser.objects.get(user=self.request.user)
form.instance.customerauthor = user
customerObj = super().forms_valid(form,inlines)
for i in inlines:
i.instance.author = user
i.instance.Customer = customerObj
i.save()
return customerObj

Matching data from two functions in django context?

I'm struggling with matching contexts in my django project. I want to insert a .annotate() queryset, perfectly in just a set variable.
I know it sounds weird but it's the best as I can describe it.
I tried using .filter(), as it makes sense to me logically, but it doesn't quite work.
my views.py
from django.shortcuts import render
from django.db.models import Count
from django.db.models import Sum
from .models import Offer_general
from .models import Offer_details
import datetime
# Create your views here.
def offer_general_list(request):
#queryset = Offer_general.objects.filter(status=1).order_by('-id')
context = {}
context["data"] = Offer_general.objects.filter(status=1).order_by('-id')#stuff from Offer_general
context["test"] = Offer_details.objects.values('fk_offer_general_id').annotate(sum=Sum('fk_offer_general_id'))
return render(request, "index_offers.html", context)
def offer_general_details(request):
context = {}
context["data"] = Offer_details.objects.all()
return render(request, "offer_detail.html", context)
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models import Count
STATUS = (
(0,"Inactive"),
(1,"Active")
)
class Offer_type(models.Model):
type = models.TextField()
class Meta:
ordering = ['-type']
def __str__(self):
return self.type
class Offer_general(models.Model):
offer_name = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
status = models.IntegerField(choices=STATUS, default=0)
type = models.ForeignKey(Offer_type, on_delete= models.PROTECT)
class Meta:
ordering = ['-id']
def __str__(self):
return self.offer_name
class Offer_localization(models.Model):
localization = models.TextField()
class Meta:
ordering = ['-localization']
def __str__(self):
return self.localization
class Offer_details(models.Model):
slug = models.SlugField(max_length=200, unique=True)
localization = models.ForeignKey(Offer_localization, on_delete= models.PROTECT, default="Opole")
fk_offer_general_id = models.ForeignKey(Offer_general, on_delete= models.PROTECT)
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
requirements = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-id']
def __str__(self):
return self.slug
TL;DR, i want the sum() returned in context["test"] to be nicely loopable, with id being equal to fk_offer_general_id.
The problem is shown in the following image:(I dont have reputation to post image :()
https://ibb.co/XtpkKpC

How can I check whether a person is included in a model to make a Job/Post

I have created a School System-like system, that creates a job and sends them to employees/users. I'm almost done making this system however I can't seem to know what do to check if the user is included in the manager model that I created to create a job.
Also, how can a user just see all their job that was assigned to them. All I know is to use objects.allbut that might only seem to show all of the jobs that was posted, I just want the user to see the job included to them.
Here is my model.py:
from django.db import models
from profiles.models import User
# Create your models here.
class Points (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
points = models.IntegerField(default=0, null=False)
def __str__(self):
return self.user.username
class Profile (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.png',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}Profile'
class Manager (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Member (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
member = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Job (models.Model):
manager = models.OneToOneField(Manager, on_delete=models.CASCADE)
member = models.OneToOneField(Member, on_delete=models.CASCADE)
title = models.CharField(max_length=30, blank=False, null=False)
description = models.TextField()
datePosted = models.DateTimeField (auto_now = True)
file = models.FileField(null=True, blank=True,upload_to='job_files')
def __str__(self):
return self.title
And Views.py:
from django.shortcuts import render
from django.views.generic import ListView, CreateView
from .models import Job
from profiles.models import User
# Create your views here.
class jobs(ListView):
model = Job
template_name = 'users/user_jobs.html'
context_object_name = 'jobs'
class createjob (CreateView):
model = Job
fields = ['member','title', 'description', 'file']
How can I proceed?
Use get_queryset to filter job by user
Ex:
class jobs(ListView):
model = Job
template_name = 'users/user_jobs.html'
context_object_name = 'jobs'
def get_queryset(self):
return Job.objects.filter(member__member=self.request.user)

TimeField displayed as date

Im using Django framework to build a simple inventory management system. There is data in the database populated using the django admin. Now when i display the data on the website (front-end), there is a time field which is displaying the date, although i am beginning to learn django, I assume my models are wrong. Below i've attached my models.py and also the error on the actual site.
Models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time
from django.db import models
class Cart(models.Model):
def __str__(self):
return self.CartColor
CartColor = models.CharField(max_length=255)
Quantity = models.CharField(max_length=5)
class Initials(models.Model):
def __unicode__(self):
return self.Staff
Staff = models.CharField(max_length=255)
FirstName = models.CharField(max_length=255)
LastName = models.CharField(max_length=255)
class RTInfo(models.Model):
def __str__(self):
return str(self.TicketNo)
TicketNo = models.CharField(max_length=10)
# TickStamp = models.DateField(auto_now_add=True, blank=True)
class Room(models.Model):
def __unicode__(self):
return self.Number
Number = models.CharField(max_length=5)
class TCCheckOut(models.Model):
def __str__(self):
return str(self.ReturnDate)
ReturnDate = models.DateField(auto_now_add=True, blank=True)
ReturnTime = models.TimeField(auto_now_add=True, blank=True, unique_for_date=True)
OutQuantity = models.CharField(max_length=255)
Staff = models.ForeignKey(Initials, on_delete=models.CASCADE)
Number = models.ForeignKey(Room, on_delete=models.CASCADE)
CartColor = models.ForeignKey(Cart, on_delete=models.CASCADE)
TicketNo = models.ForeignKey(RTInfo, related_name="custom_user1_profile", on_delete=models.CASCADE)
# TickStamp = models.ForeignKey(RTInfo,related_name="custom_pass2_profile", on_delete=models.CASCADE)
class TCCheckIn(models.Model):
def __str__(self):
return str(self.Date)
Date = models.DateField(auto_now_add=True, blank=True)
Time = models.TimeField(auto_now_add=True, blank=True)
Quantity = models.CharField(max_length=255)
Staff = models.ForeignKey(Initials, on_delete=models.CASCADE)
Number = models.ForeignKey(Room, on_delete=models.CASCADE)
CartColor = models.ForeignKey(Cart, on_delete=models.CASCADE)
TicketNo = models.ForeignKey(RTInfo, related_name="custom_user_profile", on_delete=models.CASCADE)
ReturnDate = models.ForeignKey(TCCheckOut, related_name="value1", on_delete=models.CASCADE)
ReturnTime = models.ForeignKey(TCCheckOut, related_name="timeRet", on_delete=models.CASCADE)
OutQuantity = models.ForeignKey(TCCheckOut, related_name="value3", on_delete=models.CASCADE)
Actual Error
Actual_error
As seen from the image above, even though the time is being saved, date is displayed. It was also noted that in Django admin, the said time fields display the date as well, an image has been attached below
Django_Error
I assumed that, in Django admin Return Time is supposed to be a timestamp then why is the date displayed ?
Thanks to anyone that can help!
As I mentioned in the comment, this is because of your __str__() in TCCheckOut model.
str()
Called by str(object) and the built-in functions format() and print()
to compute the “informal” or nicely printable string representation of
an object. The return value must be a string object.
To solve your problem, you can access the ReturnDate and ReturnTime by using TCCheckIn instance
In [1]: check_in = TCCheckIn.objects.get(id=1)
In [2]: check_in.ReturnDate.ReturnDate
Out[2]: datetime.date(2018, 2, 27)
In [3]: check_in.ReturnDate.ReturnTime
Out[3]: datetime.time(1, 24, 46, 440771)
By using this kind of accessing, you can display them in your template/html

Monitoring User Activity in Django

I am creating a book app where users can sign up and start reading.
This is the model.py for the book:
from django.db import models
from django.urls import reverse
from django.conf import settings
class Chapter(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(unique=True)
date_completed = models.DateTimeField(blank=True, null=True)
completed = models.BooleanField(default=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("course:subchapter_list", kwargs={"pk": self.pk})
class SubChapter(models.Model):
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(unique=True)
completed = models.BooleanField(default=False)
def __str__(self):
return self.title
class SubSection(models.Model):
sub_chapter = models.ForeignKey(SubChapter, on_delete=models.CASCADE)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(unique=True)
text = models.TextField(null=True, blank=False)
completed = models.BooleanField(default=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("course:detail",
kwargs={"slug": self.sub_chapter.slug,
"slug2": self.slug,
"pk": self.sub_chapter.chapter.pk,
}
)
How can I monitor each user's progress such that when a subsection/subchapter/chapter is viewed/read, that model instance's completed attribute is set to True just for that user? My current implementation sets completed to True for everyone.
I would appreciate code snippets demonstrating how you might implement it.
If you want to monitor the reading progress for every user, you can't have the completed fields on the Chapter, SubChapter and SubSection models, you need a new one related to the user. I would do something like this:
class ReadingProgress(models.Model):
user = models.ForeignKey(User)
completed_chapter = models.ForeignKey(Chapter)
completed_subchapter = models.ForeignKey(SubChapter)
completed_subsection = models.ForeignKey(SubSection)
If you have different books, you should add foreign keys to the book model as well.
Then in the views that fetch the chapters, sections and so on, you can get the ReadingProgress object for the specific user (and book?) and set the corresponding values.

Categories