Django Query Filter Menu - python

I want to build a similar, but significantly simpler User list page with a query filter menu:
Player List from nhl.com
User can apply individual filters, or chain them. I prefer AJAX, but am happy to start off an 'apply filters' submit button.
Current look
class User(AbstractBaseUser):
id = models.AutoField(primary_key=True)
created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
modified = models.DateTimeField(auto_now=True, null=True, blank=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(verbose_name='email address', max_length=255, unique=True, )
date_of_birth = models.DateField('date of birth', null=True)
avatar = models.ImageField('profile picture', upload_to='static/images/avatars/', null=True, blank=True)
logline = models.CharField(max_length=100, blank=True)
driving = models.BooleanField(default=False)
license_class = models.IntegerField(blank=True, null=True, choices=LICENSE_CHOICES)
vehicle = models.CharField(max_length=100, blank=True)
show = models.ForeignKey(Show, on_delete=models.CASCADE, null=True, blank=True)
links = ArrayField(models.URLField(max_length=100, blank=True, null=True), blank=True, null=True)
focus = ArrayField(models.CharField(max_length=50, null=True, choices=FOCUS_CHOICES), blank=True, null=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
call_preference = ArrayField(models.CharField(max_length=90, choices=FOCUS_CHOICES, null=True), blank=True, null=True)
blocked = models.ManyToManyField('self', related_name='blocked', blank=True)
qualified_positions = ArrayField(models.CharField(max_length=50, choices=FOCUS_CHOICES, null=True), null=True, blank=True)
years = models.IntegerField(default=1)
trade = ArrayField(
models.CharField(max_length=50, choices=TRADE_CHOICES),
null = True,
blank = True
)
member = models.BooleanField(default=False)
available = models.BooleanField(default=False)
available_from = models.DateField(null=True, blank=True)
available_to = models.DateField(null=True, blank=True)
range = DateRangeField(null=True, blank=True)
objects = UserManager()
Filters:
- Available - BooleanField, if available on date specified
- Position - CharField choices, can pick 1
- Trade - BooleanField choices, can pick multiple
- Member - Is member of selected union
Currently have generic ListView, and UserManager() full of recently typed and untested queries that likely need much work.
def base_get(self, start_date, **kwargs):
#user = kwargs.pop('user')
rightthefucktoday = datetime.date.today()
rightthefucktomorrow = datetime.date.today() + datetime.timedelta(days=1)
f = []
if start_date and 'end_date' in kwargs: ## is user.range contains the range of dates
diff = kwargs.pop('end_date') - start_date
date_range = []
for i in range(diff.days + 1):
date_range.append(start_date + datetime.timedelta(days=i))
f = self.filter(range_range=(date_range)).order_by('years', 'member')#.exclude(user=user)
return f
elif start_date and not 'end_date' in kwargs:
## if end date isn't specified
if start_date == rightthefucktomorrow:
f = self.filter(available=True).order_by('years', 'member').exclude(available_to=rightthefucktoday) ## if the date specified is tomorrow
return f
else:
f = self.filter(range_contains = start_date).order_by('years', 'member')#.exclude(user=user) # if date specified is not tomorrow
return f
else: ## no date specified, which is impssible
f = self.filter(available=True).order_by('years', 'member')#.exclude(user=user) #return if available
return f
def get_by_position(self, position):
u = self.filter(qualified_positions_contains=position)
return u
def get_by_trade(self, *args):
shit = []
for i in args:
shit.append(i)
c = self.filter(trade_contains=shit)
return c
def get_by_union(self, union): ## input must be "IATSE 891", "IATSE 669", or "ACFC 2020"
return self.filter(union__union__exact_=union)
def get_by_member(self):
return self.filter(member=True) ##if only members
def master_query(self, start_date, *args, **kwargs): ## args must be trade details TODO: Test, and build test cases
f, u, c, k = []
if 'end_date' in kwargs: f = self.base_get(start_date, kwargs.pop('end_date'))
else: f = self.base_get(start_date)
it = f
if 'position' in kwargs: u = self.get_by_position(kwargs.pop('position')); it = it | u
if 'union' in kwargs: c = self.get_by_union(kwargs.pop('union')); it = it | c
if args.count() != 0: k = self.get_by_trade(args); it = it | k
if 'member' in kwargs: you = self.get_by_member(); it = it | you
return it
If someone could nudge me in the right direction as far as handling the template and view properly - I'd love you forever
Thank you

One way to apply filters is by using GET parameters. (The parts after the '?' in URLs [e.g. https://search.yahoo.com/search?p=test+search]). So create a form in your template with method='GET' and handle the GET parameters via self.request.GET (I think you have to enable the RequestContextProcessor for this).

Related

I have written a django query but need specific user information of particular date

Models:
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, default=1,related_name='Employee')
eid = models.IntegerField(primary_key=True)
salary = models.IntegerField(null=True, blank=True)
gender = models.CharField(max_length=6, choices=GENDER_CHOICES, default=1)
contactno = models.CharField(max_length=10, blank=False)
email = models.CharField(max_length=50 ,null=True, blank=True)
country = models.CharField(max_length=30)
address = models.CharField(max_length=60)
def __str__(self):
return self.user.first_name + '_' + self.user.last_name
class Attendance(models.Model):
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, default=1,related_name='Attendance')
attendance_date = models.DateField(null=True)
in_time = models.TimeField(null=True)
out_time = models.TimeField(null=True ,blank=True)
description = models.TextField(null=True, blank=True)
def __str__(self):
return str(self.employee) + '-' + str(self.attendance_date)
class Breaks(models.Model):
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, default=1)
break_in = models.TimeField(null=True, blank=True)
break_out = models.TimeField(null=True, blank=True)
attendance =models.ForeignKey(Attendance, on_delete=models.CASCADE, default=1,related_name='Breaks')
def __str__(self):
return str(self.employee) + '-' + str(self.break_in) + '-' + str(self.break_out)
def detail_attendance(request):
attendance_list = Attendance.objects.filter(employee__user_id=request.user.id)
counter = Counter()
return render(request, 'employee/detail_attendance.html', {'attendance_list': attendance_list, 'counter': counter})
def detail_break(request):
break_list=Breaks.objects.filter(employee__user_id=request.user.id )
return render(request, 'employee/detail_break.html', {'break_list': break_list})
I have created a function above for detail breaks. I am getting specific user data, but it is giving me the previous data as well. So I need the data for specific date for example in my attendance models I adding attendance of each user.
Please let me know what should I change in detail break.
Use this Queryset:
from django.db.models import Q
from datetime import date
Breaks.objects.filter(
Q(employee__user=request.user) &
Q(attendance__attendance_date=date.today())
)
Or:
Breaks.objects.filter(
Q(employee__user=request.user) &
Q(attendance__attendance_date="2022-11-28")
)
Breaks.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Or if you are just trying to filter month wise:
Breaks.objects.filter(date__year='2011',
date__month='01')
Please reply to this message ,If it doesn't work.

Adding Data through For-Loop deletes old data

I have created a e-commerce project. I have 3 models. Item, CartItem, Placeorder(checkout). I am looping through user's cart which has multiple items so that I can get each item and make a placeorder instance. But the for loop works only for the first time and when I try to placeorder(checkout) again with multiple items, the old data(records) are deleted and replaced by new data in the for loop. I do not understand this behavior. I cannot get past this. Maybe I am making some silly mistake.
models.py
SUB_CATEGORY_CHOICES = (
('Veg','Veg'),
('Non-Veg','Non-Veg'),
)
QUANTITY_CHOICES = (
('Half','Half'),
('Full','Full')
)
class Item(models.Model):
name =models.CharField(max_length=1000)
description =models.CharField(max_length=2000)
# snacks, maincourse, soups, rice, ice-cream
category =models.CharField(max_length=1000)
# veg, non-veg
# sub_category =models.CharField(max_length=1000,blank=True,null=True)
sub_category =models.CharField(choices=SUB_CATEGORY_CHOICES, max_length=1000)
images1 =models.FileField(upload_to='food_image',blank=True,null=True)
images2 =models.FileField(upload_to='food_image',blank=True,null=True)
price =models.CharField(max_length=500)
add_date =models.DateTimeField(default=timezone.now)
# half, full
quantity_size =models.CharField(choices=QUANTITY_CHOICES,max_length=1000, blank=True,null=True)
avg_rating =models.FloatField(default='0',blank=True,null=True)
def __str__(self):
return '%s - %s - %s' % (self.id,self.name,self.price)
class Meta:
ordering = ['-add_date']
class CartItem(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
the_item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
price = models.IntegerField()
def __str__(self):
return '%s - %s' % (self.the_item.name, self.the_item.sub_category)
class Placeorder(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
order_items = models.ForeignKey(CartItem, on_delete=models.CASCADE)
item_quantity = models.IntegerField(default=1)
first_name = models.CharField(max_length=200, null=True)
last_name = models.CharField(max_length=200, null=True)
shipping_phone_number = models.IntegerField(null=True)
shipping_address_1 = models.CharField(max_length=500, null=True)
shipping_address_2 = models.CharField(max_length=500, null=True)
shipping_city = models.CharField(max_length=200, null=True)
shipping_district = models.CharField(max_length=200, null=True)
shipping_state = models.CharField(max_length=200, null=True)
shipping_zipcode = models.IntegerField(null=True)
billing_phone_number = models.IntegerField(null=True)
billing_address_1 = models.CharField(max_length=500, null=True)
billing_address_2 = models.CharField(max_length=500, null=True)
billing_city = models.CharField(max_length=200, null=True)
billing_district = models.CharField(max_length=200, null=True)
billing_state = models.CharField(max_length=200, null=True)
billing_zipcode = models.IntegerField(null=True)
payment_mode = models.CharField(default='', max_length=100,null=False,blank=False)
date_added = models.DateTimeField(default=timezone.now)
delivered = models.BooleanField(default=False)
customer_delivered = models.BooleanField(default=False)
def __str__(self):
return f'{self.user.username} -- {self.order_items.the_item}'
views.py
def checkout_page(request):
items = CartItem.objects.filter(user=request.user)
cart_total = CartItem.objects.filter(user=request.user).aggregate(Sum('price'))
context = {
'cart_total': cart_total['price__sum'],
'items':items,
'total_items':len(items),
}
return render(request, 'resto/newcheckout.html', context)
def checkout_action(request):
items = CartItem.objects.filter(user=request.user)
if request.method == 'POST':
shipping_phone_number = request.POST.get('shipping_phone_number')
shipping_address_1 = request.POST.get('shipping_address_1')
shipping_address_2 = request.POST.get('shipping_address_2')
shipping_city = request.POST.get('shipping_city')
shipping_district = request.POST.get('shipping_district')
shipping_state = request.POST.get('shipping_state')
shipping_zipcode = request.POST.get('shipping_zipcode')
billing_phone_number = request.POST.get('billing_phone_number')
billing_address_1 = request.POST.get('billing_address_1')
billing_address_2 = request.POST.get('billing_address_2')
billing_city = request.POST.get('billing_city')
billing_district = request.POST.get('billing_district')
billing_state = request.POST.get('billing_state')
billing_zipcode = request.POST.get('billing_zipcode')
payment_mode = request.POST.get('COD')
same_billing_address = request.POST.get('same_billing_address')
for item in items:
checkout_item = CartItem.objects.get(id=item.id)
print('item.pk: ', item.pk)
checkout_instance = Placeorder(
user=request.user,
order_items=item,
item_quantity=item.quantity,
first_name=request.user.first_name,
last_name=request.user.last_name,
shipping_phone_number=shipping_phone_number,
shipping_address_1=shipping_address_1,
shipping_address_2=shipping_address_2,
shipping_city=shipping_city,
shipping_district=shipping_district,
shipping_state=shipping_state,
shipping_zipcode=shipping_zipcode,
)
checkout_instance.save()
return HttpResponseRedirect(reverse('myorders'))
I gues your return HttpResponseRedirect(reverse('myorders')) should has less indent, otherwise you get return after first iteration of loop
def checkout_action(request):
items = CartItem.objects.filter(user=request.user)
if request.method == 'POST':
...
for item in items:
...
return HttpResponseRedirect(reverse('myorders'))

Displaying sum of time by project by user using Django

I am a student new to programming. I am working on a project to create a timekeeping function. I want to be able to display the total time a user worked on a project. I have been able to display the total time for a user, and the total time for a project.
class User(models.Model):
class Project(models.Model):
title = models.CharField(max_length=255)
start_date = models.DateField()
end_date = models.DateField()
done = models.BooleanField(default=False)
created_by = models.ForeignKey(User, related_name ='made_by', on_delete=models.CASCADE)
projects_working_on = models.ManyToManyField(User, related_name = "projects_assigned_to")
class Timekeeper(models.Model):
clock_in = models.DateTimeField(null=True)
clock_out = models.DateTimeField(null=True)
total_time = models.DurationField(null=True, blank=True)
entire_time = models.FloatField(null=True)
is_working = models.BooleanField(default=False)
users_time = models.ForeignKey(User, related_name="time_of_user", on_delete=models.CASCADE)
proj_time = models.ForeignKey(Project, related_name = 'time_of_project', on_delete=models.CASCADE)
Here is is clockout function:
def clockout(request, proj_id):
user = User.objects.get(id=request.session['userid'])
now = datetime.now(timezone.utc)
this_proj = Project.objects.get(id = proj_id)
this_time = user.time_of_user.last()
time = this_time.users_time
this_time.clock_out = now
this_time.is_working = False
newtime = user.time_of_user.filter(proj_time=proj_id).aggregate(Sum('total_time'))
# this_time.total_time_two = newtime
this_time.save()
Timekeeper.objects.update(total_time=F('clock_out') - F('clock_in'))
Timekeeper.objects.update(entire_time=F('total_time'))
Timekeeper.objects.update(total_time_two=newtime)
# Timekeeper.objects.update(entire_time=user.time_of_user.filter(proj_time=proj_id).aggregate(Sum"(F('total_time')")
return redirect('/dashboard/view/'+str(proj_id))
The entire_time field exists solely for another function to iterate through and find the time of all of the fields for a particular user, or project. I can't seem to get a sum of the total_times (or entire_times) of 1 user for a particular project. Any help is greatly appreciated.
Responding to my own post, I found a workable solution: Not the most elegant though.
class Timekeeper(models.Model):
clock_in = models.TimeField(null=True)
clock_out = models.TimeField(null=True)
total_time = models.FloatField(null=True, blank=True)
entire_time = models.FloatField(null=True)
user_total_time = models.FloatField(null=True, blank=True)
user_project_total_time = models.FloatField(null=True, blank=True)
is_working = models.BooleanField(default=False)
users_time = models.ForeignKey(User, related_name="time_of_user", on_delete=models.CASCADE)
proj_time = models.ForeignKey(Project, related_name = 'time_of_project', on_delete=models.CASCADE)
In views.py
def clockout(request, proj_id):
user = User.objects.get(id=request.session['userid'])
this_time = user.time_of_user.last()
total_time_of_user = 0
total_time_of_user_project = 0
for i in user.time_of_user.all():
total_time_of_user += i.total_time
this_time.user_total_time = total_time_of_user
this_time.save()
for x in user.time_of_user.filter(proj_time=proj_id).all():
total_time_of_user_project += x.total_time
this_time.user_project_total_time = total_time_of_user_project
this_time.save()
This creates 2 new attributes to the Timekeeper model.

django query to get posts from users followed by a user

My models:
class ClientProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, related_name='client_profile')
follows = models.ManyToManyField(User,
related_name='follows',blank=True)
profile_picture = models.ImageField( blank=True)
phone_regex = RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
)
mobile_number = models.CharField(validators=[phone_regex],
max_length=17, blank=True)
dob = models.DateField(auto_now = False, null = True)
profile_summary = models.TextField()
my_career_objective = models.TextField()
educational_qualification = models.CharField(max_length=200)
work_experience = models.IntegerField(blank=True, null=True)
skill_set = models.TextField(blank=True)
address_1 = models.CharField(max_length=300,blank=True)
address_2 = models.CharField(max_length=300,blank=True)
# new fileds
about_me = models.TextField(blank=True)
birthplace = models.CharField(max_length=150,blank=True)
lives_in = models.CharField(max_length=150,blank=True)
occupation = models.CharField(max_length=150, blank=True)
gender = models.CharField(choices=GENDER_CHOICES,max_length=150, blank=True)
marital_status = models.CharField(choices=MARITAL_CHOICES,max_length=150, blank=True,default=1)
religion = models.CharField(max_length=150, blank=True)
political_incline = models.TextField(blank=True)
# other_social_networks = models.TextField(blank=True)
hobbies = models.TextField(blank=True)
favorite_tv_shows = models.TextField(blank=True)
favorite_movies = models.TextField(blank=True)
favorite_games = models.TextField(blank=True)
favorite_music_band_artists = models.TextField("Favorite Music, Bands / Artists", blank=True)
favorite_books = models.TextField(blank=True)
favorite_writers = models.TextField(blank=True)
other_interests = models.TextField(blank=True)
subscription = models.TextField(blank=True, null=True, default="Free")
def __str__(self):
return str(self.user.first_name) + " " + str(self.user.last_name)
class Task(models.Model):
level = models.ForeignKey(Level, on_delete=models.CASCADE)
todo = models.ForeignKey(ToDo, on_delete=models.CASCADE)
student = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
content = models.TextField()
timestamp = models.TimeField(auto_now=True)
datestamp = models.DateField( auto_now=True)
like = models.ManyToManyField(User,related_name='user_likes',blank=True)
is_verified=models.BooleanField(default=False,blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('student:dashboard')
objects = PostManager()
#property
def comments(self):
instance = self
qs = Comment.objects.filter_by_instance(instance)
return qs
#property
def get_content_type(self):
instance = self
content_type =
ContentType.objects.get_for_model(instance.__class__)
return content_type
I want to display all tasks from logged in user and also all the tasks from all users followed by logged in user.What is the best django query to implement this? the follows field in the ClientProfile model is given as many to many field to depict all users followed by the user.How to write django query with 'or'.Each task points to a user through foreign key 'student' . I want to display all tasks from logged in user and all users followed by logged in user in the homepage
Put a related_name attribute in student field of Task. (let's call it task)
If logged_in_user is your logged in user object then logged_in_user.task would give task of logged_in_user and for user's followers tasks:
tasks = Task.objects.filter(student__in= logged_in_user.follows.all())
Without related_name.
task = Task.objects.filter(Q(student=logged_in_user) | Q(student__in=logged_in_user.follows.all()))
This worked for me :
client=ClientProfile.objects.get(user=request.user)
task = Task.objects.filter
(Q(student=request.user) |
Q(student__in=client.follows.all()))
.order_by('timestamp').prefetch_related('images_set')

How to check the details of foreignkey before creating object in the form?

In the Django project I'm working on there is model called Course and it contains many Assignment objects.
This is a part of models.py:
class Assignment(models.Model):
course = models.ForeignKey(Course, related_name='get_assignments')
name = models.CharField(max_length=200)
ipaddress = models.CharField(null=True, max_length=500)
publish_type = models.CharField(max_length=50, default="Scheduled")
type_of_lab = models.CharField(max_length=50, default="Lab")
timeduration = models.DurationField(default=timedelta(seconds=0), null=True)
late_duration = models.DurationField(default=timedelta(seconds=0), null=True)
exam_group_id = models.CharField(max_length=50, null=True)
serial_number = models.IntegerField()
program_language = models.CharField(max_length=32)
duration = models.DurationField(default=timedelta(seconds=0), null=True)
freezing_duration = models.DurationField(default=timedelta(seconds=0), null=True)
deadline = models.DateTimeField(null=True)
freezing_deadline = models.DateTimeField(null=True)
publish_on = models.DateTimeField(null='true')
bulk_add = models.FileField(max_length = 800,upload_to=assignment_bulk_upload_path, null=True)
When creating an assignment through form, the form is validated using some functions. This is part of forms.py:
class AssignmentForm(forms.Form):
assignment_type = forms.BooleanField(required=False, widget=forms.HiddenInput())
name = forms.CharField(label="Assignment Name", widget=forms.TextInput(attrs={'placeholder':'Assignment Name (200 Characters or fewer)','maxlength':200}))
Typeof = (('Lab', 'Lab'), ('Exam', 'Exam'))
publishtype = (('Scheduled', 'Scheduled'), ('On Demand', 'On Demand'))
publish_type = forms.ChoiceField(
choices=publishtype,
label="Choose type of Publish (Default : Scheduled)"
)
duration = forms.DurationField(
label="Assignment Duration",
required=False,
help_text="Assignment Duration, input format is HH:MM:SS "
)
freezing_duration = forms.DurationField(
label="Freezing extra time",
required=False,
help_text="Extra time for students to freeze submission, input format is HH:MM:SS "
)
bulk_add = forms.FileField(
error_messages={'invalid': 'File was not a valid tar file.'},
required=False,
label="Add sections and/or test cases in bulk",
)
#
#
# some more code
#
#
def clean_bulk_add(self):
assig1 = self.cleaned_data['name']
course1 = self.this_course
user1 = course1.owner
tot1 = 30 + len(str(user1)) + len(str(course1.title)) + len(str(assig1)) + len(str(self.cleaned_data['bulk_add']))
if tot1 > 700 :
raise forms.ValidationError("Assignment or Course name is too long: "+str(tot1))
return self.cleaned_data['bulk_add']
def clean_name(self):
if not hasattr(self, 'this_course'):
return self.cleaned_data['name']
try:
_ =Assignment.objects.filter(trash=False).get(name=self.cleaned_data['name'], course=self.this_course)
raise forms.ValidationError('This assignment already exists in this course.')
except Assignment.DoesNotExist:
pass
return self.cleaned_data['name']
As you can see while validating AssignmentForm I want to use the name of course in which it is created. So in function clean_bulk_add, I've written course1 = self.this_course.
Then it is showing AttributeError 'AssignmentForm' object has no attribute 'this_course'. So, how to get the name of course in which it the Assignment is going to be created?

Categories

Resources