How to annotate a define a query in django with authenticated - django

I want to do a django filter that is ordered by authenticated user objects.
Something like this, but the authenticated users objects first in the returned queryset:
user = self.request.user
Company.objects.filter(status="approved")
The Company model has a foreign key user as below:
Company(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
default=1,
on_delete=models.CASCADE,
related_name="companies",
)
Note: I am NOT trying to get just the user's objects.

Related

Django ORM Query Optimization Issue

I am making a blog website and I am facing some issues with the Query performance.
I have 3 models
User Model -> Users (To store user email, Password etc)
Post Model -> Actual Posts
people Model -> (To store users extra information)
Post Model ->
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
title = models.CharField(max_length=255,null=True)
description = models.CharField(max_length=1000,null=True)
Likes = models.ManyToManyField(to=User, related_name='Post_likes')
favourites = models.ManyToManyField(to=User,blank=True,related_name="favourite")
People Model ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Now as both of these models are connected to User model. I want to query the Post model and get the user photo in the template. Now when I use post.user.people.photo then for every post it generates a seperate query to DB resulting in slowness. I would like to use Join here to combines multiple tables and fetch all the records at once.
I am currently using following Query ->
posts = Post.objects.select_related().prefetch_related('images_set').annotate(comments_Count = Count('comments_post',distinct=True)).annotate(Count('Likes',distinct=True)).all().order_by('-id')
You can perform a .select_related(…) [Django-doc] on the user and the people with user__people, so:
posts = Post.objects.select_related(
'user__people', 'category'
).prefetch_related('images_set').annotate(
comments_Count = Count('comments_post',distinct=True),
Count('Likes',distinct=True)
).order_by('-id')
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django ORM query by related name

I am trying to query all the customer of a particular seller/user
This is my sell model
class Sell(models.Model):
entry_for = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='sell_entry_for'
)
paid_by = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='sell_customer',
null=True,
blank=True
)
and this is my query
user = User.objects.filter(
sell_entry_for__id=<user id>
)
and return empty but I have many entries for the user
Can anyone help me to fix this issue?
I believe you want something like:
user = User.objects.get(id=user_id_here)
# now you want to get all related Sell objects with that user
sells = user.sell_entry_for.all()
# now you can iterate over sells to get paid_by users
for sell in sells:
print(sell.paid_by)

Django subscriber feature

I am creating a django site/platform where the main concept is users can create shops and other users can subscribe to those who have shops open (think Etsy). Trying to implement the subscriber feature and this is a model I have so far for it:
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
It works perfect for giving users the ability to subscribe and have the subscribtions listed in their profile and vice versa for shop owners, but for now a user can subscribe to a shop as many times as they want and I would like to prevent this. Idk if there is a constraint to allow multiple subscriber model instances by the same user but not allow for the same exact 'user' and 'sub_shop' instance OR if I am just going on about this in a very bad way!
You can use a UniqueConstraint [Django-doc] to specify that the combination of user and sub_shop should be unique:
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'sub_shop'],
name='subscribe_once'
)
]
prior to django-2.2, you can work with unique_together [Django-doc]:
# prior to Django-2.2
class Subscriber(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
sub_shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
class Meta:
unique_together = [['user', 'sub_shop']]
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

How to query reverse foreign key in django?

I am trying to filter queryset for a reverse foreign key.
Here are my two models:-
class BranchModel(basemodel.BaseModel):
company = models.ForeignKey(CompanyModel, on_delete=models.PROTECT)
name = models.CharField(max_length=30, default="Head Office")
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='branch_owner')
class User(AbstractUser):
id = models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False
)
objects = UserManager()
I want to get all the users of a branch.
I tried to use this queryset:-
User.objects.filter(branchmodel__user=self.request.user)
but it is giving me empty result.
how can i modify this?
I assume you want all branches of user as per your model setup. Below code will gives you all branches of request.user
user=self.request.user
prtnt(user) # to check user in terminal
userbranches=user.branch_owner.all()

How to allow users In Django to see specific data from same model

I am facing a problem while giving permission to admin users in Django that how to restrict users to see only user specific data from same model. I mean that if 2 user can add data to same model, then how to restrict them to access only that data.
in that model you need to specify which user inserted that value. If you have User model, then you can add new field to your model as User which is ForeignKey field.
When you inserted your data with user property, you can easily filter them with user (user.id)
For example if you have Customer model you can filter the value with user's id (in this case it's merchant_id):
customer = Customer.objects.filter(email=email, merchant_id=merchant_id).all()
And our model looks like this:
class Customer(models.Model):
merchant = models.ForeignKey(Merchant, on_delete=models.DO_NOTHING)
name = models.CharField(max_length=128, null=True)
surname = models.CharField(max_length=128, null=True)
email = models.EmailField(max_length=255, null=True)
and you can define a permissions like:
class Task(models.Model):
...
class Meta:
permissions = [
("change_task_status", "Can change the status of tasks"),
("close_task", "Can remove a task by setting its status as closed"),
]
and you can check that via:
user.has_perm('app.close_task')
Hope it helps,