zoukankan      html  css  js  c++  java
  • python django的ManyToMany简述

    Django的多对多关系

    在Django的关系中,有一对一,一对多,多对多的关系
    我们这里谈的是多对多的关系

    我们首先来设计一个用于示例的表结构

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.db import models
    
    # Create your models here.
    
    
    class Book(models.Model):
        name = models.CharField(max_length = 32)
    
        def __str__(self):
            return self.name.decode("utf-8")
    
        def __unicode(self):
            return self.name.decode("utf-8")
    
    
    class Author(models.Model):
        name = models.CharField(max_length = 32)
        m = models.ManyToManyField('Book')
    
        def __str__(self):
            return self.name.decode("utf-8")
    
        def __unicode(self):
            return self.name.decode("utf-8")
    

    我们可以看到,这个多对多的关系在 作者这个表里
    事实上,多对多多关系可以存在于任何一方
    我们现在把这个关系放在作者这一方
    作者和书籍是多对多的关系
    我们现在来创造一些测试数据

    In [1]: from app_many_models_01 import models
    
    In [2]: models.Author.objects.create(name = u'张三')
    Out[2]: <Author: 张三>
    
    In [3]: models.Author.objects.create(name = u'赵一')
    Out[3]: <Author: 赵一>
    
    In [4]: models.Author.objects.create(name = u'张六')
    Out[4]: <Author: 张六>
    
    In [5]: models.Author.objects.create(name = u'李七')
    Out[5]: <Author: 李七>
    
    In [6]: models.Book.objects.create(name = u'python编程')
    Out[6]: <Book: python编程>
    
    In [7]: models.Book.objects.create(name = u'Go编程')
    Out[7]: <Book: Go编程>
    
    In [8]: models.Book.objects.create(name = u'Java编程')
    Out[8]: <Book: Java编程>
    
    In [9]: models.Book.objects.create(name = u'shell编程')
    Out[9]: <Book: shell编程>
    
    In [10]: models.Book.objects.create(name = u'Lua编程')
    Out[10]: <Book: Lua编程>
    
    In [11]: models.Book.objects.create(name = u'Ruby编程')
    Out[11]: <Book: Ruby编程>
    
    In [12]: models.Book.objects.create(name = u'PHP编程')
    Out[12]: <Book: PHP编程>
    
    In [13]: models.Book.objects.create(name = u'Perl编程')
    Out[13]: <Book: Perl编程>
    
    In [14]: models.Book.objects.create(name = u'AI编程')
    Out[14]: <Book: AI编程>
    

    通过上面的测试数据,我们创建了作者表和书籍表
    下面我们进行表的关系的编写

    In [1]: from app_many_models_01 import models
    
    In [2]: p = models.Book.objects.get(name = "Python编程")
    
    In [3]: php = models.Book.objects.get(name = "PHP编程")
    
    In [4]: pe = models.Book.objects.get(name = "Perl编程")
    
    In [5]: zhangliu = models.Author.objects.get(name = u"张六")
    
    In [6]: zhang = models.Author.objects.get(name = u"张三")
    
    In [7]: li  = models.Author.objects.get(name = u"李七")
    
    In [8]: zhao = models.Author.objects.get(name = u"赵二")
    

    到此,我们仍然没有为表之间创建关系
    那么,开始吧

    In [18]: zhao.m.add(p)
    
    In [65]: zhang.m.create(name=u"Basic编程")
    Out[65]: <Book: Basic编程>
    
    In [66]: zhang.m.add(php)
    
    In [67]: zhang.m.add(pe)
    
    In [68]: zhang.m.add(p,php,pe)
    
    In [69]: zhang.m.add(p,php,pe,go)
    

    上面都是从作者表出发的添加关系的操作
    zhang是我们拿到的对应到 张三的 这个作者的对象
    zhang.m 对应到表之间的关系就是作者表里面的多对多关系的书籍表对象
    zhang.m.add就是给作者表的书籍表这个对应关系添加上具体的对应指向
    而zhang.m.create这个很有意思,zhang.m其实就是跨表了,跨到了书籍表,到了书籍表,自然可以创建书籍啊,那么这就是创建书籍对象
    add方法可以一次添加一个关系,也可以一次添加多个关系


    我们再从书籍表出发,来添加两个表之间的映射关系

    In [73]: zhang.m.create(name=u"vb编程")
    Out[73]: <Book: vb编程>
    
    In [74]: b = models.Book.objects.get(name = u"vb编程" )
    
    In [75]: b.author_set.all()
    Out[75]: <QuerySet [<Author: 张三>]>
    

    其实从上面我们已经可以看出来了
    因为多对多的关系是放在作者表中的,那么类似一对多的关系的是
    从一的那一方出发,都是用到XXX_set这种映射
    就拿到了这个一对应的多(而这里其实是多对多)的多的那一方的跨表查询的结果
    通过这个跨表查询的操作,就可以干你想干的事情了

    mysql> use test_many_models;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> select * from app_many_models_01_author;
    +----+--------+
    | id | name   |
    +----+--------+
    |  1 | 张三   |
    |  2 | 赵一   |
    |  3 | 张六   |
    |  4 | 李七   |
    +----+--------+
    4 rows in set (0.00 sec)
    mysql> select * from app_many_models_01_author_m;
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    | 11 |         1 |       1 |
    | 16 |         1 |       2 |
    | 14 |         1 |       7 |
    | 15 |         1 |       8 |
    | 12 |         1 |      14 |
    | 13 |         1 |      15 |
    | 17 |         1 |      16 |
    |  7 |         3 |       3 |
    |  6 |         3 |       9 |
    | 18 |         4 |      16 |
    +----+-----------+---------+
    10 rows in set (0.00 sec)
    
    

    通过查询结果,我们可以看到,已经成功的添加了vb编程这本书籍的作者了,并且是从书籍这张表出发添加的
    说完了添加关系操作,我们再谈谈删除和清除关系的操作

    In [77]: zhang.m.remove(b)
    

    
    mysql> select id  from app_many_models_01_book  where name="vb编程";
    +----+
    | id |
    +----+
    | 16 |
    +----+
    1 row in set (0.00 sec)
    
    mysql> select * from app_many_models_01_author_m;
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    | 11 |         1 |       1 |
    | 16 |         1 |       2 |
    | 14 |         1 |       7 |
    | 15 |         1 |       8 |
    | 12 |         1 |      14 |
    | 13 |         1 |      15 |
    | 17 |         1 |      16 |
    |  7 |         3 |       3 |
    |  6 |         3 |       9 |
    | 18 |         4 |      16 |
    +----+-----------+---------+
    10 rows in set (0.00 sec)
    
    mysql> select * from app_many_models_01_author_m;
    +----+-----------+---------+
    | id | author_id | book_id |
    +----+-----------+---------+
    | 11 |         1 |       1 |
    | 16 |         1 |       2 |
    | 14 |         1 |       7 |
    | 15 |         1 |       8 |
    | 12 |         1 |      14 |
    | 13 |         1 |      15 |
    |  7 |         3 |       3 |
    |  6 |         3 |       9 |
    | 18 |         4 |      16 |
    +----+-----------+---------+
    9 rows in set (0.00 sec)
    

    remove操作就是删除某个或者多个关系(可以一次传入多个参数)
    可以看到,经过了remove操作,就把 vb编程这本书籍从张三这个作者的相关书籍中去掉了


    我们再来看clear操作

    mysql> select id  from app_many_models_01_author where name = "李七";
    +----+
    | id |
    +----+
    |  4 |
    +----+
    1 row in set (0.00 sec)
    
    mysql> select book_id  from app_many_models_01_author_m where author_id="4";
    +---------+
    | book_id |
    +---------+
    |      16 |
    +---------+
    1 row in set (0.00 sec)
    

    在执行clear操作前,我们可以看到作者李七有一本书籍,编号是16,即vb编程
    那么,我们开始执行clear操作

    In [78]: li.m.clear()
    

    我们再来看看现在李七这个作者还有什么书籍?

    mysql> select book_id  from app_many_models_01_author_m where author_id="4";
    Empty set (0.00 sec)
    

    可见,clear这种操作是清除关系的,把某个关系全部清除

  • 相关阅读:
    第三章-套接字编程
    unix网络编程第四章----基于TCP套接字编程
    unix网络编程第一章demo
    unix网络编程第2章
    论epoll的实现
    Select函数实现
    函数式编程语言
    Git
    python库-urllib
    PIL处理图片信息
  • 原文地址:https://www.cnblogs.com/haozike/p/python_django_ManyToMany.html
Copyright © 2011-2022 走看看