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
Related
I have been reading through here and I can't seem to find the answer of the question I am looking for. Maybe I'm not asking the correct question.
I have three models.
Recruiter
Office
Recruit
Recruiters are assigned to multiple offices and each office has multiple employees. What I need to be able to do is create a listview that lists all of the employees that are associated with a recruiter. So something like this:
Recruiter 1 has Office 1 and 2 assigned to them. Office 1 has Employee 1,2,3. Office 2 has employee 3,4,5
The Listview should display all employees under Recruiter 1.
My Models are:
class Recruit(models.Model):
id = models.CharField(max_length=25,primary_key=True, unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
mobile_phone = models.CharField(max_length=20,null=True)
preferred_phone = models.CharField(max_length=20,null=True)
email= models.CharField(max_length=100,null=True)
officeid = models.ForeignKey(Office,on_delete=models.DO_NOTHING,related_name="recruit")
class Office(models.Model):
office_name = models.CharField(max_length=100)
officeid = models.CharField(max_length=20,primary_key=True,unique=True)
class Recruiter(models.Model):
user = models.OneToOneField(User, related_name='recruiter',on_delete=models.CASCADE)
organization = models.ForeignKey(UserProfile,on_delete=models.CASCADE)
Do I need a AssingedOffices table to join this all together?
class AssignedOffice(models.Model):
user = models.ForeignKey(UserProfile,on_delete=models.CASCADE)
esa_office = models.ForeignKey(Office,on_delete=models.CASCADE)
Just not sure how to connect them & display in the listview.
Edit Added start of view.
class MyESA(LoginRequiredMixin,ListView):
template_name = "recruits/recruits_list.html"
user= User.objects.select_related('recruiter')
paginate_by = 20
model=Recruit
context_object_name = 'recruits'
def get_queryset(self):
queryset = Recruit.objects.filter(probablity=1)
return queryset
If you want to achieve a Many-to-one relationship like this
Recruiters are assigned to multiple offices
then you should have a ForeignKey in the Office model not the other way around. I presume that each Office has one Recruiter. Otherwise you should have a Many-to-Many relationship that is constructed with a ManyToManyField
I presume that by
each office has multiple employees
You meant that each Office object has multiple Recruit objects
If you want to list all of the Recruit objects in a ListView for model Recruiter then I think the easiest way would be to add a ForeignKey field in the Recruit model and refer to it via related object reference
I have created a model called Department, Course. Models are as follow
This is the model for departments and course
class Departments(models.Model):
Department_Id = models.IntegerField(primary_key=True)
Department_Name = models.CharField(max_length=200)
Department_Code = models.CharField(max_length=200)
class Course(models.Model):
Course_Id = models.IntegerField(primary_key=True)
Department_Id = models.ForeignKey(Departments, on_delete=models.CASCADE)
Course_Name = models.CharField(max_length=200)
Course_Code = models.CharField(max_length=200)
I want to create a model called view which can be later on called for search. I want a view model in a such a way that it consit of the data in concat form i.e. name= Department_name+ Course_Name
class View (models.model):
view_id= models.IntegerField(primary_key=True)
Name= Department_name(I want this from Departments table)
+ Course_Name(I want this from Course table)
I try using one to one relation . I would really appricate the help
It's not clear why you'd want to do that. It's never a good idea to duplicate data from one model into another one, as it can lead to inconsistencies.
You can add a ForeignKey in View to your Course model and then when you do f"{view.course.name} {view.course.department.name}" you already have your string:
class View(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def name(self):
return f"{self.course.name} {self.course.department.name}"
Notes:
Don't call your foreign key Department_id because it's not referring to the id but to the object itself in the Django ORM: department = models.ForeignKey(Department, on_delete=models.CASCADE). As you can see, this makes reading the code much simpler: self.course.Department_id is a Department object not an integer, so self.course.department makes more sense.
Don't prefix your field names with the class, it just makes the code so much less readable: Do you prefer department.name or department.Department_name?
The View model is still a mystery to me, as you can search without it. You can search for example for courses with a matching department name like this:
Course.objects.filter(department__name__icontains="maths")
which will return all courses with "maths" in their department name.
Remove all the ids from your models, they are created automatically by Django anyway (and called id). Again, department.id is much easier to read than department.Department_id. Also in your code, you have to generate the ids yourself since you don't set them to auto-populate.
I would like to do a reverse relationship on my table Tickets.
Here is my model :
class Tickets(models.Model):
ticket_title = models.CharField(max_length=100)
ticket_content = models.TextField()
class User_Detail(models.Model):
user = models.OneToOneField(User)
tickets = models.ManyToManyField(Tickets, blank=True, null=True)
I create my ticket like that :
ticket = Tickets.objects.create(ticket_title="test", ticket_content="test content")
request.user.user_detail.tickets.add(ticket)
and the thing I'm having an issue to do is to get the username of the guy who post the ticket, (without request.user)
so I tried like that :
ticket = Tickets.objects.get(pk=1)
ticket.user_detail_set.user.username
but I get
AttributeError: 'ManyRelatedManager' object has no attribute 'user'
Thanks you for watching, I hope you'll understand.
Since you set up a many-to-many relationship, a Ticket may have many User_Detail objects. Therefore, Ticket.user_detail_set is a manager, not a single object. You could get the first user associated with a Ticket like this:
ticket.user_detail_set.first().user.username
But it sounds like you actually want a one-to-many relationship between Ticket and User_Detail, meaning you actually want Ticket to have a foreign key relationship. Your models should probably look like this:
class User_Detail(models.Model):
user = models.OneToOneField(User)
class Ticket(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=100)
contents = models.TextField()
Then you can do:
ticket = Ticket.objects.get(pk=1)
user = ticket.user
You might even be able to drop the User_Detail model entirely, unless you use it elsewhere in your application and/or it has more fields than what is shown here.
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()
I have a model suppose
class A(models.Model):
name = models.CharField(max_length=256)
class B(models.Model):
city = models.CharField(max_length=256)
users = models.ManyToManyField(A)
Now can I say if I have to save these models I can use
users = A.objects.all()
and suppose I have a data for to store as
b = B(city="XYZ", user=users).save()
that is can I use directly the complete query set to store the manytomany field data.
You can't pass a many-to-many field when you instantiate a model, in any case.
After the model is saved, though, you can do:
b.users.add(*users)