Giving a model knowledge of a many-to-many related model in django

筅森魡賤 提交于 2020-01-23 16:54:24

问题


EDIT: Given responses in comments and answer I tried suggestion and I get some errors when trying to query , also doing the related name query does not get the right results (as seen in comments)

BusinessLocations.objects.all()

Error: QuerySet object has no attribute 'objects' is the error.

In either case, I did a dump of all the tables and see this:

auth_business_permissions', u'auth_permission', u'auth_user', u'auth_user_businesss', u'auth_user_user_permissions', u'django_admin_log', 
u'django_content_type', u'django_migrations', u'django_session', u'ipaswdb_address', u'ipaswdb_billing', u'ipaswdb_billing_businesss', 
u'ipaswdb_designation', u'ipaswdb_business', u'ipaswdb_business_business_locations', u'ipaswdb_businessinsurances', u'ipaswdb_businessinvoices', 
'ipaswdb_businesslocations', u'ipaswdb_businessterm', u'ipaswdb_insurance', u'ipaswdb_insurance_businesss', u'ipaswdb_invoice', u'ipaswdb_employee',
u'ipaswdb_employeeinvoice', u'ipaswdb_employeelocations', u'ipaswdb_employeeterms', u'ipaswdb_specialty']

I have a ipaswdb_business_business_locations and a ipaswdb_businesslocations which seems strange to me, and I wonder if my database is just gunked up?

Original Question:

I have two models a Business and an Employee. I want them both to be aware of each other but not directly but through another model called a 'BusinessesLocation`. I can sort of express this in my models but it doesn't look or feel right. It is like only the employee knows of the businesses, and not vice vice versa.

I had another question opened to try to answer this but the answer was not 100% correct in that it didn't offer for a many to many it was more like a one to many. In this case: An employee can work at many locations (potentially being an employee of many businesses) and a business can have many locations having many employees.

Currently my models work where this shell script works:

someEmployee.business_locations.all()[0].business.business_name and it works fine, I can get all the locations of a business an employee works at and via that infer the many businesses an employee might work for given the businesses locations.

But I cannot figure out how to go the other way, and find out all the employees a business has working for them and at which locations

My current (wrongish) models are like this:

class Employee(models.Model):
        first_name = models.CharField(max_length = 50)
        business_locations = models.ManyToManyField('BusinessLocations', through='EmployeeLocations')


class EmployeeLocations(models.Model):
    employee = models.ForeignKey('Employee', on_delete=models.CASCADE)
    business_location = models.ForeignKey('BusinessLocations', on_delete=models.CASCADE)
    created_at=models.DateField(auto_now_add=True)
    updated_at=models.DateField(auto_now=True)
    def __str__(self):
        return self.provider.first_name

class BusinessLocations(models.Model):
    address = models.ForeignKey('Address', on_delete= models.SET_NULL, null=True)
    business = models.ForeignKey('Business', on_delete=models.CASCADE)
    doing_business_as = models.CharField(max_length = 255)
    created_at=models.DateField(auto_now_add=True)
    updated_at=models.DateField(auto_now=True)
    def __str__(self):
        return self.doing_business_as

class Business(models.Model):
    business_name = models.CharField(max_length=50)
    business_locations = I need something here no idea how

Bellow is some pseudo shell code demonstrating how I would like my models to work:

#create a new business location assume business has been created
newLocation = Address(...)
business.business_locations.add(newLocation, doing_business_as='alternative name maybe')


#assume employee exists
#add a new business location to the employee
#when i say selected business the form would have current employee then in its locations
#you'd have to select a business first, and get a list of all that businesses locations and you
#you could add the business location and then select another business with all ITS locations
# and add one there too if you wish

employee.employee_locations.add(selectedBusiness.business_locations[0])
employee.employee_locations.add(anotherSelectedBusiness.business_locations[1])

Below is what I cannot figure out how to do, vice versa... 

#now lets see which businesses the employee works for.

for business in employee.business_locations
       business.business_name

#and lets see each businesses employees:
for employee in Employee.objects.all()
       employee.
?? No idea how to build the models to represent these relationships

I can get an employees business locations just fine, but I cannot get the above examples of getting a list of employees for a business. Not sure what I need to adjust (or methods I might need?) to get this to work like I want in my shell example.


回答1:


What you're missing is Django's concept of related objects.

When you define a relationship in a model (i.e., a ForeignKey, OneToOneField, or ManyToManyField), instances of that model will have a convenient API to access the related objects.

You can access the related objects both in queries and as a manager attribute on your models. See the examples in the documentation. In your case this would look something like:

# Now lets see which businesses the employee works for:
Business.objects.filter(businesslocations__employee=employee).distinct()

# And let's see each business's employees:
Employee.objects.filter(business_locations__business=business).distinct()


来源:https://stackoverflow.com/questions/38233245/giving-a-model-knowledge-of-a-many-to-many-related-model-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!