How to search for objects in the Django User model - django

I have a Profile model:
from django.contrib.auth.models import User
class Profile(models.Model):
first_name = models.CharField(max_length=100, blank=True)
last_name = models.CharField(max_length=100, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
birthday = models.DateField(null=True, blank=True)
bio = models.TextField(blank=True, max_length=1000)
location = models.CharField(max_length=100, blank=True)
...
And a search contacts view:
class SearchContactsView(ListView):
model = Profile
template_name = 'users/contact_search.html'
context_object_name = 'qs'
def get_queryset(self):
q1 = self.request.GET.get('contact_name')
q2 = self.request.GET.get('contact_location')
if q1 or q2:
return Profile.objects.filter(Q(first_name__icontains=q1) |
Q(last_name__icontains=q1),
location__icontains=q2)
return Profile.objects.all()
It is working fine but I would like to be able to search for contacts via the user field as well. Does anyone know a way to do that?
EDIT my user's username's are created by them when they sign up to the site and are currently uneditable. They are displayed on the admin page via a dropdown since they are a OneToOneField. I think my issue is that django recognises them only as an IntegerField('pk') but I need to somehow cast them as a string value. Am I right in thinking that, and if so how can this be achieved?

You can add to your template to allow user to input user_username and save that username to q3:
q3 = self.request.GET.get('user_username')
After that you can adjust your If condition accordingly, then change your return to something like:
Profile.objects.filter(Q(first_name__icontains=q1) |
Q(last_name__icontains=q1),
location__icontains=q2,
user__username=q3)

Related

Filter and get all the customers who had brought the authors other contents to send the notification when new content is added

I want to Filter and get all the customers who had brought the authors other contents to send the notification when new content is added This works on queryset I know but I'm Confused on how to do that. If anyone please share.
Here are my models
content:
class Content(models.Model):
title = models.CharField(max_length=1000)
Author = models.ForeignKey('User',on_delete=models.CASCADE)
slug = AutoSlugField(populate_from='title', unique=True, null=False)
cover = models.ImageField(upload_to='course', default='nocover.jpg')
catogary = models.ForeignKey(Category, on_delete=models.RESTRICT)
description = models.TextField(max_length=2000, null=True, blank=True)
requirements = models.TextField()
price = models.FloatField()
language = models.ForeignKey(Language, on_delete=models.RESTRICT)
Puchased content
class PurchasedContent(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
course = models.ForeignKey(Course, blank=True, related_name='course')
I want all the list of Customers email who had brought a particular Authors course
the Author will be authenticated while adding. We'll get the Author as request.user
Here is sample ListCreateAPIView in django rest Framework
class createlistcontentview(generics.ListCreateAPIView):
permission_classes = [TokenHasReadWriteScope]
queryset = Content.objects.all()
serializer_class = ContentSerializer
def perform_create(self, serializer):
#Here I want to get a list of mails to create a Function that sends mall
serializer.save(author=self.request.user)
So what you can do is use a signal to send the email to the users whenever a content is created like this:
from django.dispatch import receiver
# models.py
#receiver(models.signals.post_save, sender=Content)
def send_email(sender, instance:Content, created, **kwargs):
if created:
# import and use your email helper here
# since the related name you chose for the purchased_content course is a little confusing I changed it to `purchased_content`
purchases = instance.course.purchased_content.all()
send_email(users=[user.email for user in purchases])
return

Fetching data from models using OneToOneField in Django

well my college is making us go learn a framework and make a website with it in a month, and it's really killing me, because of that I couldn't really get a good understanding of the Django framework as I am making progress while watching YouTube vids and reading docs.
Anyways my models are all messed up which made the job even harder, and whenever I solve a problem another one arises, but the deadline is close and making any changes to the models will cost me a great deal of time. This time my problem is about fetching data.
The concerned models are the following:
The User class for authentication
class User(AbstractBaseUser, PermissionsMixin):
id = models.AutoField(primary_key=True,null=False)
username = models.CharField(max_length=50)
email = models.EmailField(unique=True)
nom = models.CharField(max_length=255)
prenom = models.CharField(max_length=255)
usertype = models.CharField(choices=types,max_length=20,default="user")
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
is_superuser = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
student_data = models.OneToOneField(Etudiant, on_delete=models.CASCADE,blank=True, null=True,related_name='Etudiant_access')
Prof_data = models.OneToOneField(Prof, on_delete=models.CASCADE,blank=True, null=True)
objects=UserManager()
def __str__(self):
return self.prenom + " " + self.nom
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
The Students(Etudiant) class for managing the students:
class Etudiant(models.Model):
filiere = models.ForeignKey(Filiere, on_delete=models.DO_NOTHING)
classe = models.ForeignKey(Classe,null=True, on_delete=models.DO_NOTHING)
notes = models.ManyToManyField(note,blank=True, null=True)
The class Classe (LMAO) for managing the different classes:
class Classe(models.Model):
#Cla_id = models.AutoField(primary_key=True, null=False)
Designation = models.CharField(max_length=100)
filiere = models.ForeignKey(Filiere, on_delete=models.CASCADE)
Epreuve = models.ManyToManyField(Epreuve,blank=True, null=True)
def __str__(self):
return self.Designation
The thing is that I wanna fetch all data of the Users that are students (which means that their Prof_data attribute is blank/null and their student_data attribute is pointing to the Etudiant(Student) class while having an Etudiant.classe attribute equals to a value in the view's parameters
I've solved a great deal of it but I'm stuck at the end
This is my view function:
#login_required
def class_info(request,design):
#getting the Classe(s) from the url which Designation == design
classe_now = Classe.objects.get(Designation=design)
print(classe_now) # This works like a charm
#getting the Students objects that are part of the class_now
Etudiants = Etudiant.objects.filter(classe=classe_now)
print(Etudiants) # This works too. It returns the 'Etudiant' objects from where i wanna access to the Users data
#getting the User data of the student objects (This is where i get confused)
students_to_show = User.objects.filter(student_data=Etudiants)
pprint(students_to_show)
return render(request, 'Prof/class_info.html')
I am really confused, you are truly my last hope in this, and thank you for your time.
You can filter your User model by selecting all users that do have empty/null relation to Prof model and nonempty/null relation to Etudiant model.
student_users = User.objects.filter(Prof_data__isnull=True, student_data__isnull=False)
then for each stident_user, you can fetch its student data in the following manner:
student_user = student_users[0]
student_user.student_data.filiere
student_user.student_data.classe
student_user.student_data.notes
You can then pass the queryset result to the render function as a context variable. Check this brief tutorial on how to pass data to templates.

Display all Employees with present and absent status

I Have Two models
User Model and DailyPresent model with user as foreign_key in DailyPresent model.
class DailyPresentReport(models.Model):
PRESENT = 'present'
ABSENT = 'absent'
ON_LEAVE = 'on_leave'
PRESENT_CHOICES = (
(PRESENT, 'Present'),
(ABSENT, 'Absent'),
(ON_LEAVE, 'On Leave'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='daily_present_report')
present = models.CharField(max_length=10, choices=PRESENT_CHOICES, default=ABSENT)
punch_in = models.DateTimeField(null=True, blank=True)
punch_out = models.DateTimeField(null=True, blank=True)
date = models.DateField(null=True, blank=True)
work_time = models.DurationField(null=True, blank=True)
class Meta:
ordering = ['id']
def __str__(self):
return f'{str(self.user)}: {self.present}'
If User logs in then he is automatically made present
but when user doesn't login nothing happens.
Now I want to display a table with all users with Present and Absent Fields.
Please help me.. Thanks in advance
you can use Q module, processing the combination of "or" conditions when searching:
from django.db.models.query_utils import Q
dailyPresents = DailyPresentReport.objects.filter(Q(present="PRESENT") |
Q(present="ABSENT"))
or use .exclude to exclude the On Leave:
dailyPresents = DailyPresentReport.objects.exclude(present="ON_LEAVE")

Cannot add data into django ManyToManyfield

I have this two models:
class Posts(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="posts")
creation_date = models.DateTimeField(auto_now_add=True, blank=True)
content = models.TextField(null=True)
class User(AbstractUser):
follows = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='followed_by')
likes = models.ManyToManyField(Posts, related_name='liked_by')
pass
And I want to add a post to someone`s likes field, so i do:
def change_like(request, post_id):
post = Posts.objects.get(id=post_id)
current_user = User.objects.filter(username=request.user.username).first()
current_user.likes.add(post)
print(post.liked_by)
print(current_user.likes)
But it prints this:
network.User.None
network.Posts.None
Why is this happening? Am I adding the data correctly?
It is adding data into the ManyToMany Field. But you have printed using wrong method.
You can get all the likes of user by current_user.likes.all().
Django Docs: https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/

How to add the values ​of several fields in sql and create one from that sum using Django?

I am studying Django and SQL and I have proposed to create a social network in which I can add all the reactions of a publication and add it to a new field where they are all added.
from django.db import models
# Create your models here.
class Post(models.Model):
# User
user = models.OneToOneField(User, on_delete=models.CASCADE)
post = models.TextField(max_length=500000)
# Data
comments = models.IntegerField()
reactions = models.IntegerField()
## Reaction Data
like = models.IntegerField()
love = models.IntegerField()
wow = models.IntegerField()
sad = models.IntegerField()
angry = models.IntegerField()
That is the model of publications, there is a field called reactions, and that will be the sum of all the reactions that publication has acquired. How can I create that sum?
Such architecture will be a little wrong.
from project_name import settings
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
text = models.TextField()
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='post_likes')
love = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='post_loves')
# ... another reactions
created_date = models.DateTimeField(default=timezone.now)
settings.AUTH_USER_MODEL is your User
After that you will then be able to not only know the number of reactions, but also to identify users
To count users:
post = Post.objects.create(author=..., ...) # create post
queryset = post.likes # will return users id, who liked post
queryset.count() # will return number of users