一、多对多关联管理器(对象调用)
前提:多对多(双向均有关联管理器)一对多(只有多的那个类的对象有关联管理器,即反向才有) 语法格式:正向:属性名反向:小写类名加 _set注意:一对多只能反向 常用方法:add():用于多对多,把指定的模型对象添加到关联对象集(关系表)中。注意:add() 在一对多(即外键)中,只能传对象( *QuerySet数据类型)不能传 id(*[id表])。*[ ] 的使用:
二、多对多的应用(用户:电影(N:M))CRUD操作
(1) models.py
#电影模型
class Movie(models.Model):name=models.CharField(max_length=150)duration=models.IntegerField(default=90)class Meta:db_table='movie'verbose_name='电影'verbose_name_plural=verbose_name#用户模型
class Customer(models.Model):name=models.CharField(max_length=150)age=models.IntegerField(default=18)#设置多对多关联 FKmovies=models.ManyToManyField(Movie)class Meta:db_table='customer'verbose_name='用户'verbose_name_plural=verbose_name
(2)views.py
from django.http import HttpResponse
from django.shortcuts import renderfrom manytomany.models import Customer, Movie
def addCustomer(request):# 添加10个用户for i in range(1, 11):Customer.objects.create(name=f'mike{i}', age=i)return HttpResponse('用户添加成功!')def addMovie(request):# 添加10个用户for i in range(1, 11):Movie.objects.create(name=f'流浪地球{i}', duration=100 + i)return HttpResponse('电影添加成功!')# 正向:属性
def add_c_m(request):# 方式一:传对象# 获取用户对象# customer=Customer.objects.get(id=2)# # 获取电影对象 id<5# movie_list=Movie.objects.filter(id__lt=5)# # 将 id 小于5的电影对象添加到用户集合中# customer.movies.add(*movie_list)# 方式二:传对象 id# 获取用户对象customer = Customer.objects.get(id=3)# 将 id=7 和 id=8 的电影对象添加到用户集合中customer.movies.add(*[7, 8])return HttpResponse('用户-电影添加成功!')# 反向:小写表名_set
# create():创建一个新的对象,并同时将它添加到关联对象集之中。
# 返回新创建的对象。
def add_m_c(request):# 获取电影对象movie = Movie.objects.filter(name='流浪地球5').first()# 获取用户对象customer = Customer.objects.filter().first()# 添加mcmc = movie.customer_set.add(customer)return HttpResponse('电影-用户set添加成功!')# remove():从关联对象集中移除执行的模型对象。
# 对于 ForeignKey 对象,这个方法仅在 null=True(可以为空)时存在,无返回值。
def del_c_m(request):# 获取电影对象# movie=Movie.objects.get(id=7)# # 获取用户对象# customer = Customer.objects.filter(pk=3).first()# # 移除中间表 3-7# movie.customer_set.remove(customer)# 获取用户对象customer = Customer.objects.filter(pk=2).first()# 移除中间表 2-2customer.movies.filter(name='流浪地球2').delete()return HttpResponse('电影-用户删除成功!')#查找
# 正向:属性名
def find_cm(request):# 获取用户对象customer = Customer.objects.filter(pk=2).first()#获取用户下所有的电影ll=customer.movies.all()print(customer,ll)#循环显示for m in ll:print(m.name,m.duration)return HttpResponse('用户-电影查询成功!')# 反向:小写表名_set
def find_mc(request):# 获取电影对象movie=Movie.objects.get(id=8)#获取电影下所有的用户cc=movie.customer_set.all()print(movie,cc)#循环显示for c in cc:print(c.name,c.age)return HttpResponse('电影-用户查询成功!')# 查询用户2所有电影。
# 正向:通过 属性名称__跨表的属性名称(movies__name) 跨表获取数据:
def find_cm2(request):# 获取用户对象所有的电影customer = Customer.objects.filter(movies__customer__name='mike2').values_list('movies__name')print(customer)#循环显示for m in customer:print(m)return HttpResponse('用户-电影查询成功!')# 查询流浪地球8的所有用户。
# 反向:通过 小写类名__跨表的属性名称(customer__name) 跨表获取数据:
def find_mc2(request):# 获取电影下所有的用户movie=Movie.objects.filter(name='流浪地球8').values_list('customer__name','customer__age')print(movie)#循环显示for c in movie:print(c)return HttpResponse('电影-用户查询成功!')
(3)urls.py
from manytomany.views import * #导入视图urlpatterns = [#manytomanypath('manytomany/add',addCustomer),path('manytomany/add2',addMovie),path('manytomany/add3',add_c_m),path('manytomany/add4',add_m_c),path('manytomany/del',del_c_m),path('manytomany/find',find_cm),path('manytomany/find2',find_mc),path('manytomany/find3',find_mc2),path('manytomany/find4', find_cm2),]
(4) 运行
customer 表数据 movie表数据
customer_movies 中间表数据
正向:根据传对象
正向:根据传对象id
删除 3-7
删除 2-2
、
添加5-78910
查找用户2下所有的电影
(1)正向:属性名
查找电影编号8下所有的用户(2)反向:小写表名_set
查找用户mike5下所有的电影
正向:通过 属性名称__跨表的属性名称(movies__name) 跨表获取数据:
查询流浪地球8的所有用户
反向:通过 小写类名__跨表的属性名称(customer__name) 跨表获取数据: