Django Relational database lookups - django

I cant figure out how to do relationships.
I have a products model and a stores model.
A product has a foreign key to the stores.
So i would like to get the product name, and the store name in the same lookup.
Since the products model is:
class Products(models.Model):
PrName = models.CharField(max_length=255)
PrCompany = models.ForeignKey(Companies)
And the company model is:
class Companies(models.Model):
ComName = models.CharField(max_length=255)
How do i make django return ComName (from the companies model) when i do:
Prs = Products.objects.filter(PrName__icontains=ss)

Assuming you get results:
Prs[0].PrCompany.ComName # Company name of the first result
If you want all the company names in a list:
company_names = [product.PrCompany.ComName for product in Prs]

Related

Django filter queryset of a models that are related with a foreign key to other model?

I have a simple question.
I have two models(Waiter and Manager) and they both contains same foreign key to restaurant as:
class Managers(BaseUser):
restaurant = models.ForeignKey(Restaurants, on_delete=models.CASCADE)
class Waiters(BaseUser):
restaurant = models.ForeignKey(Restaurants, on_delete=models.CASCADE)
And restaurant model:
class Restaurants(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(max_length=250)
location = models.CharField(max_length=200)
rating = models.DecimalField(null=True, decimal_places=2, max_digits=5)
So I need to get all waiters that restaurant=managers__restaurant_id.
I think in SQL would be:
select *
From Waiters w
Left outer join Managers m
On w.restaurant_id = m.restaurant_id
Note*
I'm able to query that like below:
manager = Managers.objects.filter(id=request.usr.id)
queryset=Waiters.objects.filter(restaurant=manager.restaurant_id)
But is there any way that i could do it in one query.
But is there any way that i could do it in one query.
This is in one query, but it will work with a subquery is probably not that efficient.
You can however filter in a more compact way with:
Waiters.objects.filter(restaurant__managers=request.user.id)
We can look "through" relations by using double underscores (__). Here we thus are looking for Waiters objects for which it restaurant is related to a Managers object with the given id of request.user.id.
how about this??
queryset = Managers.objects.filter(id=request.usr.id and Waiters.objects.filter(restaurant=manager.restaurant_id))

Django union two tables into single model

I have an external database which I can't modify in any way (read-only). It has three tables - Company (id), CompanyContact (company_id, contact_id), Contact (id, company_id).
Basically, Contact has a nullable foreign-key to Company table and it works as many-to-one, but if company_id is null, I have to look into CompanyContact table, which is many-to-many kind relationship.
How can I combine these two tables (Contact and CompanyContact) into one model - Contact? In other words, how can I get all contacts for a given company?
In SQL that would be something like:
select contact.id from contact where company_id = XXX
union
select contact_id from companycontact where company_id = XXX
Django models:
class Company(models.Model):
uuid = models.CharField(max_length=36, primary_key=True, db_column='id')
class Meta:
managed = False
class Contact(models.Model):
uuid = models.CharField(max_length=36, primary_key=True, db_column='id')
company = models.ForeignKey(Company, db_column='company_id')
class Meta:
managed = False
I don't have a model for CompanyContact. And there is nothing to show in views because that basically is my question, how to get contacts for a given company.
The original tables in your database are not properly structured. It's incorrect that the contact field should have a company_id field. That needlessly complicates all queries (raw SQL or Django) because an additional check is needed on the contact_id field.
On the other hand it's perfectly legit for two entities in a many to many relationship to have exactly one mapping instead of many. So there isn't one clear answer to this question. I suppose your best bet would be to add a ManyToMany field as well. I am making this suggestion purely on the fact that you say the data is read only
class Contact(models.Model):
uuid = models.CharField(max_length=36, primary_key=True, db_column='id')
company = models.ForeignKey(Company, db_column='company_id')
companies = models.ManyToManyField(Company, related_name='companies')
class Meta:
managed = False

Get objects that are foreign key

I need ot get objects that are foreign keys. Example
class City(models.Model):
.....
class User(models.Model):
city = models.ForeignKeu(City)
.......
Can i get only that cities which are Foreign key to model User with django orm or mysql?
Yes you can, it's all in the Documentation:
https://docs.djangoproject.com/en/1.6/ref/models/querysets/
Provide a readable backward reference to the city model (in your User model change city to this one):
city = models.ForeignKey(City, related_name='user')
Then
cities = City.objects.select_related('user').filter(user__city__isnull=False).all()

Django: foreign key queries

I'm learning Django and trying to get the hang of querying foreign keys across a bridging table. Apologies if this is a duplicate, I haven't been able to find the answer by searching. I've got models defined as follows
class Place(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
class PlaceRef(models.Model):
place = models.ForeignKey(Place) # many-to-one field
entry = models.ForeignKey(Entry) # many-to-one field
class Entry(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=10)
If I want to retrieve all the Entries associated with a particular Place, how do I do it?
place = get_object_or_404(Place, id=id)
placerefs = PlaceRef.objects.filter(place=place)
entries = Entry.objects.filter(id.....)
Also, if there is a more sensible way for me to define (or get rid of) PlaceRefs in Django, please feel free to suggest alternatives.
Thanks for helping out a beginner!
First, I'd suggest rewriting the models to:
class Place(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
class Entry(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=10)
places = models.ManyToManyField(Place, related_name='places')
So you can query:
Entry.objects.filter(places__id=id)
In your current model:
Entry.objects.filter(placeref_set__place__id=id)
Note that the double underscore __ is used to jump from one model to the next. Also, django creates some fields on the model that help you navigate to related objects. In this example: Entry.placeref_set. You can read more about it here:
http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward

django manytomany through

If I have two Models that have a manytomany relationship with a through model, how do I get data from that 'through' table.
class Bike(models.Model):
nickname = models.CharField(max_length=40)
users = models.ManyToManyField(User, through='bike.BikeUser')
The BikeUser class
class BikeUser(models.Model):
bike = models.ForeignKey(Bike)
user = models.ForeignKey(User)
comment = models.CharField(max_length=140)
And I would add a user to that bike (presuming I have a myBike and a myUser already)
BikeUser.objects.create(bike = myBike, user = myUser, comment = 'Got this one at a fancy store')
I can get all the users on 'myBike' with myBike.users.all() but how do I get the 'comment' property?
I would like to do something like
for myBikeUser in myBike.users.all():
print myBikeUser.comment
The through table is linked by standard ForeignKeys, so you do a normal ForeignKey lookup. Don't forget that there's a comment for each bikeuser, ie one for each bike/user pairing.
for myBikeUser in myBike.bikeuser_set.all():
print myBikeUser.comment, myBikeUser.user.first_name