How make users own their data in django - python

Currently, if you’re logged in, you’ll be able to see all the products, no matter
which user you’re logged in as.how can i show merchants only the products that belongs to them.
i try this
views.py
def users_homepage(request):
product=Product.objects.filter(merchant=request.user).order_by('date_added')
and i get this error " Cannot query "mustapha": Must be "Merchant" instance"
my models.py
class Merchant(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE, primary_key=True)
class Product(models.Model):
merchant=models.ForeignKey(Merchant, on_delete=models.CASCADE)
date_added = models.DateTimeField(auto_now_add=True)

Use user to get a merchant instance and the use that to query products.
def users_homepage(request):
merchant = Merchant.objects.get(user=request.user)
product = Product.objects.filter(merchant=merchant).order_by('date_added')
Another way to do this is using [default] related name.
def users_homepage(request):
product = Product.objects.filter(merchant=request.user.merchant).order_by('date_added')

Try
def users_homepage(request):
product=Product.objects.filter(merchant__user=request.user).order_by('date_added')

Related

Django: Confusion with accessing database model's foreign key data

This is my first time working with Django and while working I have encountered with a confusion to create a particular statement in views that leads to my desired output. I have created a model 'Parents' which has data of a specific student (Foreign Key), and I am confused to access that student id for further process like working with Attendance, or Results of that specific student. Below are necessary codes and my trial to fetch data.
Models.py
class Students(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
gender = models.CharField(max_length=50)
address = models.TextField()
course_id = models.ForeignKey(Courses, on_delete=models.DO_NOTHING, default=1)
session_year_id = models.ForeignKey(SessionYearModel, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager()
def __str__(self):
return self.admin.first_name + " " + self.admin.last_name
class Parents(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
gender = models.CharField(max_length=50)
**student = models.ForeignKey(Students, on_delete=models.CASCADE)**
relation = models.CharField(max_length=255)
address = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager()
def __str__(self):
return self.admin.first_name + " " + self.admin.last_name
Here I have two models, Students model has all information regarding student and the other model is Parent model which has parent information with its specific student id.
Below is the views file code where I am trying to fetch student id of currently logged in parent,
def HOME(request):
stud_data = Parents.objects.filter(student__id = request.user.id)
print(stud_data)
return None
At the time of page reload, I am able to get an empty QuerySet[] as it is not able to find the id.
Kindly help me finding the solution to this problem, so that I can continue thinking about the development.
Thanks :)
As you mentioned here, you are looking for Student data for currently logged in Parent. Hence you can look for Student data directly from Parent object. Like this:
stud_object = request.user.parent.student
This relation works because Parent has a OneToOne relation with CustomUser (I assume Authentication's custom User model), hence you should get Parent object from request.user.parent (reverse relation for OneToOne). Also, student field is a ForeignKey of Parent model.
Addionally, I think the relation between Parent and Student should be ManyToMany, because a Student can have multiple parents and one parent can have multiple students (or children).
There are two possibilities:
The View code that you have attached should be returning stud_data not None, but I am assuming that you know this and this current state of the code is just for debugging purposes.
The request.user.id contains a value that doesn't belong to any student's ID in the database. As you are using filter, it's not going to complain about it and just return you an empty QuerySet. I'd suggest using the get() filter here which raises the DoesNotExist exception and would help in debugging as well.
def home(request):
stud_data = Parents.objects.get(student__id = request.user.id)
return stud_data
Hope it helps!
Best of luck with your new journey!

Filter Objects that are related to an object by another relationship

class Shipping (models.Model):
phone_number = models.CharField(max_length=14)
email = models.EmailField()
class Package(models.Model):
name = models.CharField(max_length=30)
supplier = models.ForeignKey( Supplier , on_delete=models.DO_NOTHING)
to = models.ForeignKey(Shipping, default=None, on_delete=models.CASCADE )
I have these Django models and as you see every package has shipping(to) and a supplier who is a user. How can I filter Shipping objects that are related to the package with a specific supplier in my views?
I want to be able to get all Shipping objects a supplier has ever send packages to.
You can try like this:
Shipping.objects.filter(package__supplier=<supplier_object>)
Basically you can run reverse query from Shipping to Package models via package__<field_name> attribute(model name all lowecase unless you have defined a related name, then it would be <related_name>__<field_name>.
More information can be found in documentation.
I think that you can do something like the following thing:
shippings = []
for package in Package.objects.filter(supplier=supplier_you_want).all():
shippings.append(package.to)
hope that could help!
The below line will return all the shippings corresponding to your_supplier.
shippings=Package.objects.filter(supplier=your_supplier).values('to__phone_number','to__email')

Using multiple columns as ForeignKey to return in another table

I'm new to Django so I make 3 simple tables to return a WishList. The thing is that I want whenever user asks for WishList, his/her user_id is used to make a SELECT query to return his/her own WishList. And I want to get product title and product url from my WishList table. I'm using to_field but with that way I only can get product title back. I don't know much about Django so help me!
Product
class Product(models.Model):
class Meta:
unique_together = (('id', 'title'),)
title = models.CharField(max_length=200, unique=True,
help_text='Name of the product')
url = models.CharField(max_length=300, default='',
help_text='Url of the product')
def __str__(self):
return 'Product: {}'.format(self.title)
WishList
class WishList(models.Model):
class Meta:
unique_together = (('user', 'product'),)
user = models.ForeignKey(fbuser,
on_delete=models.CASCADE,
help_text='Facebook user',
to_field='user_id')
product = models.ForeignKey(Product, to_field='title', db_column='title',
on_delete=models.CASCADE)
def __str__(self):
return 'WishList: {}'.format(self.user)
It's not a good practice to override to_field to another field different than your model.pk unless you have a really good reason and you know what you are doing (definitely not the case right now).
So after you read the docs, you will know that in order to get wishlisht related to a user, you can use the ForeignKey reverse relation to get all related wishlists for a user.
user_wishlists = my_user.wishlist_set.all()
#Because we know that you want to access the wishlist.products
#in order to optimize things (in terms of db queries)
#you can add and .select_related('product')
#e.g, user_wishlists = my_user.wishlist_set.all().select_related('product')
#now follow the wishlist.product foreign key to access the related product for every wishlist
for wishlist in user_wishlists:
product = wishlist.product
print (product.id, product.title, product.url)
Now after you read a little bit more of the documentation
you will notice that your WishList model is in fact an intermediate model for a ManyToMany relation between User and his wished products, then you will know that you can define a M2M field between user and products via WishList like so:
class FbUser(models.Model):
#...
wished_products = models.ManyToManyField(
Product,
through='WishList',
through_fields=('user', 'product')
)
#and now accessing user wished products would be easy as:
user_wished_products = my_user.wished_products.all()
for product in user_wished_products:
print (product.id, product.title, product.url)

Django: How to properly make shopping cart? ( Array string field )

Lately I've been needing to create a server-side shopping cart for my website that can have products inside. I could add cart and product in session cookies, but I prefer to add it to my custom made User model, so it can stay when the user decides to log out and log back in.
Since I'm making a shopping cart, I need to make a model for it, that will hold products as objects, so then they can be easily used, but I can't find any way to do so properly.
class User(models.Model):
username = models.CharField(max_length=150)
joined = models.DateTimeField('registered')
avatar = models.CharField(max_length=300)
balance = models.IntegerField(default=0)
ban = models.BooleanField()
cart = models.???
def __str__(self):
return self.username
How can I achieve having array string in models with using Django's system? If not then can it be possible by other libraries ( Json, Pickle ), but I've seen it can be done by ForeignKey, if so how is it possible?
I'd suggest using DB relationships instead of storing a string or an array of strings for this problem.
If you solve the problem using DB relationships, you'll need to use a ManyToManyField.
class User(models.Model):
...
cart = models.ManyToManyField(Product)
And assuming you have a model for your products.
class Product(models.Model):
name = models.CharField(max_length=30)
price = models.DecimalField(max_digits=8, decimal_places=2)
When adding elements to the cart you'll use something like this.
tv = Product(name='LED TV', ...)
tv.save()
diego = User.objects.get(username='dalleng')
diego.cart.add(some_product)

Query Django model using name from another model

I'm building a project that involves a list of people and the transactions they've made. Each person will have their own profile with x amount of transactions.
My database, so far, consists of two models:
One to define a person
class Person (models.Model):
"""
A person
"""
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, blank=True)
def __unicode__(self):
return self.name
One to associate a transaction each person made.
class Purchase (models.Model):
"""
A purchase for each person
"""
person_id = models.ForeignKey(Person)
purchase_description = models.CharField(max_length=1000, blank=True)
I determined this would be a many-to-one database relationship because some people might make the same transaction.
Now, I can make pages for each person, showing their name in the header. What I'd like to do is show the transactions made to that particular person. How can this be done? Here's what my view.py file looks like:
from django.shortcuts import render
from .models import Person, Purchase
def load_person(request, name):
person = Person.objects.get(name=name)
# name = Purchase.objects.filter(purchase)
context = {
'name': name
# 'purchase': purchase
}
return render(request, 'pages/person.html', context)
Here's the url associated to the query in my url.py file.
url(r'^project/(?P<name>[-\w]+)/$', views.load_person),
person = Person.objects.get(name=name)
purchases = Purchase.objects.filter(person_id=person)
Sounds like you just started using django, there are several things that are not best practice, they are:
You don't need to define id in Person, django will define it for you.
Try not to use person_id as field name, use person instead. Django model is not relational database design, think of the models as separate entities.

Categories

Resources