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) 跨表获取数据:

相关推荐
豌豆花下猫5 分钟前
Python 潮流周刊#78:async/await 是糟糕的设计(摘要)
后端·python·ai
YMWM_7 分钟前
第一章 Go语言简介
开发语言·后端·golang
只因在人海中多看了你一眼9 分钟前
python语言基础
开发语言·python
小技与小术16 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
码蜂窝编程官方24 分钟前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
hummhumm42 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
杜小满1 小时前
周志华深度森林deep forest(deep-forest)最新可安装教程,仅需在pycharm中完成,超简单安装教程
python·随机森林·pycharm·集成学习
J老熊1 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
AuroraI'ncoding1 小时前
时间请求参数、响应
java·后端·spring
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang