Django 模型操作 - 多对多(九)

一、多对多关联管理器(对象调用)

复制代码
前提:
        多对多(双向均有关联管理器)
        一对多(只有多的那个类的对象有关联管理器,即反向才有)
语法格式:
        正向:属性名
        反向:小写类名加 _set
        注意:一对多只能反向
常用方法:
        add():用于多对多,把指定的模型对象添加到关联对象集(关系表)中。
        注意:add() 在一对多(即外键)中,只能传对象( *QuerySet数据类型)
             不能传 id(*[id表])。*[ ] 的使用:

二、多对多的应用**(用户:电影(N:M))CRUD操作**

(1) models.py

python 复制代码
#电影模型
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)
    #设置多对多关联 FK
    movies=models.ManyToManyField(Movie)

    class Meta:
        db_table='customer'
        verbose_name='用户'
        verbose_name_plural=verbose_name

(2)views.py

python 复制代码
from django.http import HttpResponse
from django.shortcuts import render

from 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()
    # 添加mc
    mc = 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-2
    customer.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

python 复制代码
from manytomany.views import *   #导入视图

urlpatterns = [

    #manytomany
    path('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) 跨表获取数据:

相关推荐
我是李武涯2 分钟前
PyTorch Dataloader工作原理 之 default collate_fn操作
pytorch·python·深度学习
LucianaiB7 分钟前
招聘可以AI面试,那么我制作了一个AI面试教练不过分吧
后端
Kratzdisteln43 分钟前
【Python】绘制椭圆眼睛跟随鼠标交互算法配图详解
python·数学·numpy·pillow·matplotlib·仿射变换
maxruan1 小时前
PyTorch学习
人工智能·pytorch·python·学习
无奈何杨1 小时前
CoolGuard更新,ip2region升级、名单增加过期时间
后端
唐古乌梁海1 小时前
【python】在Django中,执行原生SQL查询
python·sql·django
摇滚侠2 小时前
Spring Boot 3零基础教程,WEB 开发 自定义静态资源目录 笔记31
spring boot·笔记·后端·spring
Anthony_49262 小时前
逻辑清晰地梳理Golang Context
后端·go
小宁爱Python2 小时前
Django Web 开发系列(二):视图进阶、快捷函数与请求响应处理
前端·django·sqlite
程序员大雄学编程2 小时前
「用Python来学微积分」5. 曲线的极坐标方程
开发语言·python·微积分