Access intermediary model values Django - django

I have a simple question. using the example from django above. How can i get for example the invite_reason from Person on a Group ? or all joined dates to all groups from that person ? thanks.
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)

You'll need to query your Membership model for that, like so:
memberships = Membership.objects.filter(person=person, group=group)
for membership in memberships:
membership.invite_reason
Alternately, you could query it based on the relation:
memberships = person.membership_set.filter(group=group)
for membership in memberships:
membership.invite_reason

Related

How to perform query in Django

I need to filter the a particular user's bar in whcih reservations were made. I am a beginner in Django and have tried some methods which unfortunately didn't work.
models.py
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
class Bar(models.Model):
user_id = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Tables(models.Model):
table_no = models.CharField(max_length=14, unique=False)
bar = models.ForeignKey(to=Bar, on_delete=models.CASCADE)
def __str__(self):
return self.table_no
class Reservation(models.Model):
first_name = models.CharField(max_length=200)
table = models.ForeignKey(Tables, on_delete=models.CASCADE)
def __str__(self):
return self.first_name
Note: I wan to filter the reservations made in a particular user's bar
I know you might be having a hard time and its one the things you go through when you are learning..
1.Can you change this first
from
class Bar(models.Model):
user_id = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
To
class Bar(models.Model):
user_id = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=50, null=True)
def __str__(self):
return self.name
2.On querying your data can you can try this since our user will already on the bar
user_bar = Bar.objects.filter("Here you specify what you wanna filter by")
Or
user_bar = Bar.objects.get(id=pk)
When I used this query filter. it worked perfectly.
reservations = Reservation.objects.filter(table__bar__user_id=request.user)
subject title: People can come to the restaurant and book a reservation filling a form which uses the Reservation model. Then the reservation is connected to a Table which is connected to a bar and the owner of the bar. Now I need to be able to filter the reservations made in each bar owner restaurant.

Django many to many field add with through model fields

I have the models below, and I want to add a member to a group in a view. How could I do this, also adding the date_joined and invite_reason correctly. I am using forms without the generics views.
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
To create the reltationship you have to base your form on the relationship model:
class MembershipForm(ModelForm):
class Meta:
fields = ['person', 'group', 'date_joined']
model = Membership
This form will be composed of a select for the persons, a select for the group and a datefield for the date_joined

Django query using ManytoManyField

Using example code:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
How could I get the name of the last 5 persons and their group's name order by date_joined? Something like:
"name1" "group1" "19/02/2019"
"name2" "group1" "19/02/2019"
"name1" "group2" "19/02/2019"
"name3" "group1" "18/02/2019"
"name4" "group2" "17/02/2019"
I have tried many options but I am not able to do it :S Thanks in advance.
You can get this by following
Membership.objects.values('person__name', 'group__name', 'date_joined').order_by(date_joined)[:5]

Model person to be able to have 1 or more first names out of which one is primary

This is my Person class. How should I modify this to make person be able to have 1 or more first names out of which one is primary?
class Person(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
owner = models.ForeignKey('auth.User', related_name='persons')
identity_number = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Meta:
ordering = ('created',)
You can create another model to store the person names, something like:
class PersonName(models.Model):
name = models.CharField(max_length=255)
primary = models.BooleanField(default=True)
person = models.ForeignKey('Person')
def __str__(self):
return self.name
You can access the names from any person object using person.personname_set

Django Filter Query Foreign Key

I'm struggling getting the right query for my project.
Here is an example or my model :
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
how do I get publisher from the book class for example I want to get all publisher for all books that have the title starting with 'hello'?
If you want to get Publishers, you have to start with Publisher. That means you have to query through the Book → Publisher relation backwards. Here's what the docs say about it:
Lookups that span relationships
To span a relationship, just use the field name of related fields across models, separated by double underscores, until you get to the field you want
...
To refer to a “reverse” relationship, just use the lowercase name of the model.
The query:
Publisher.objects.filter(book__title__startswith='hello')