zoukankan      html  css  js  c++  java
  • python 全栈开发,Day73(django多表添加,基于对象的跨表查询)

    昨日内容回顾

    多表方案:
        如何确定表关系呢?
        表关系是在2张表之间建立的,没有超过2个表的情况。
        那么相互之间有2条关系线,先来判断一对多的关系。
        如果其中一张表的记录能够对应另外一张表的多条记录,那么关系线成立!
    
    如果只有一条线成立,那么就是一对多的关系。
    如果有2条线成立,那么就是多对多的关系。
    
    比如book和publish。一本书不能对应多个出版社(常规是这样的,否则就盗版了),那么不成立。
    一个出版社可以对应多本书,关系线成立。所以book和publish表的关系是一对多的关系
    
    多对多的关系,就是2张表互相对应多条记录。
    比如book和author。一本书可以有多个作者,一个作者可以写多本!
    
    一对一的关系,就很简单了,彼此唯一。
    比如author和authordetail是一对一的关系。
    
    
    一对多:
        book和publish表的关系是一对多的关系
    
        一旦确定一对多的关系:在多的表中创建关联字段
            </span><span style="color: #008000;">#</span><span style="color: #008000;"> 与Publish建立一对多的关系,外键字段建立在多的一方</span>
            publish=models.ForeignKey(to=<span style="color: #800000;">"</span><span style="color: #800000;">Publish</span><span style="color: #800000;">"</span>,to_field=<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>,on_delete=<span style="color: #000000;">models.CASCADE)
            </span><span style="color: #008000;">#</span><span style="color: #008000;">创建的字段名为publish_id。它会自动加_id后缀</span>
    
    多对多: book和author是多对多的关系
        一旦确定多对多的关系:创建第三张关系表
            </span><span style="color: #008000;">#</span><span style="color: #008000;"> 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表</span>
            authors=models.ManyToManyField(to=<span style="color: #800000;">"</span><span style="color: #800000;">Author</span><span style="color: #800000;">"</span><span style="color: #000000;">)
            </span><span style="color: #008000;">#</span><span style="color: #008000;">注意:表名为应用名+book类名小写+authors,也就是book_authors。</span>
            <span style="color: #008000;">#</span><span style="color: #008000;">它只有3个字段,分别是主键id,book_id,author_id。</span>
            <span style="color: #008000;">#</span><span style="color: #008000;">book_id和author_id分别表示book表和author表的主键id</span>
    
    一对一: author和authordetail是一对一的关系
        一旦确定一对一的关系 : 创建关联字段(任意一张表创建都可以)
        </span><span style="color: #008000;">#</span><span style="color: #008000;">但是一般,我们会判断谁是重要的,谁是次要的。在重要的表上面创建关联字段!比如author</span>
        <span style="color: #008000;">#</span><span style="color: #008000;">由于authordetail表是author表的延伸,所以在author表创建关联字段</span>
        <span style="color: #008000;">#</span><span style="color: #008000;"> 与AuthorDetail建立一对一的关系</span>
        ad=models.OneToOneField(to=<span style="color: #800000;">"</span><span style="color: #800000;">AuthorDetail</span><span style="color: #800000;">"</span>,to_field=<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>,on_delete=<span style="color: #000000;">models.CASCADE,)
        </span><span style="color: #008000;">#</span><span style="color: #008000;">创建的字段名为ad_id,它会自动加_id后缀。一对一关联字段,必须设置唯一属性!</span></pre>
    
    View Code

    一、django多表添加

    昨天已经把5张表,都创建出来了。models.py里面有4个模型,其中第5张表,是book表和author表的关系表。

    由book类的authors属性来创建了关系表,表名为:应用名+book+'_'+authors。

    修改urls.py,添加add路径

    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add/', views.add),
    ]
    View Code

    由于pycharm对sqlite数据库的时间字段,添加时,会自动转换为时间戳。

    这样很不好,所以我使用navicat来连接。

    新建一个连接

    找到表publish

     添加2条记录

    添加表记录

    create(**kwargs) 建立新对象

    返回值是添加的model对象

    一对一

    举例:添加一条作者信息

    姓名=hong,年龄=25,女朋友=唐安琪,电话=1314

    def add(request):
        #先添加作者详细信息
        hong_gf = AuthorDetail.objects.create(gf="唐安琪",tel=1314)
        #再添加作者,因为它依赖AuthorDetail表
        hong = Author.objects.create(name="hong",age="25",ad=hong_gf)
        print(hong)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    注意:因为author的ad属性是关联authordetail表,必须添加authordetail表,才能添加author表。

    ad必须接收一个model对象。可以从这个model对象中,获取插入的id值。

    刷新页面,查看authordetail表,发现多了一条记录

    查看author表,发现多了一条记录

    一对多

    方式1(推荐)

    修改views.py,增加add视图函数

    from django.shortcuts import render,HttpResponse
    from app01.models import Book
    # Create your views here.
    

    def add(request):
    #publish_id就是Book类的publish属性。它的字段为publish_id
    book = Book.objects.create(title='西游记',price=100,pub_date="1743-4-12",publish_id=2)
    print(book.title) #打印title
    return HttpResponse('添加成功')

    View Code

    访问url:http://127.0.0.1:8000/add/

    查看book表记录,发现多了一条

    方式2

    添加一本书《三国演义》,指定出版社为西瓜出版社

    首要要导入Publish

    def add(request):
        xigua = Publish.objects.filter(name="西瓜出版社").first()  #model对象
        book = Book.objects.create(title='三国演义',price=300,pub_date="1643-4-12",publish=xigua)
        print(book.title) #打印标题
        print(book.publish)  # 与这本书籍关联的出版社对象
        print(type(book.publish))  # 打印属性
        print(book.publish.id)  # 出版社id
        print(book.publish.name)  # 出版社name
    
    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    注意:xigua它是一个model对象,它表示publish表的一条记录

    create里面的publish只能接收publish表的model对象,不能接收别的表model对象!

    查看models.py的Book类的publish属性

    publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)

    注意:它只能接收publish表的id字段。

    所以执行sql时,它相当于publish_id=xigua.id。

    这种添加方式,有严格的限制,必须接收publish的model对象才可以的。不推荐使用

    查看控制台信息:

    三国演义
    [29/Jun/2018 16:47:44] "GET /add/ HTTP/1.1" 200 12
    Publish object (1)
    <class 'app01.models.Publish'>
    1
    西瓜出版社
    View Code

    book.publish 是与这本书籍关联的出版社对象

    那么就可以得到出版社的id和name属性值

    查看表记录,发现多了一条

    现在书籍和作者还没有绑定关系,先增加作者详细记录
    修改authordetail表,增加2条记录

    修改author表,增加2条记录

    多对多

    现在需要在book表里面插入一本书《python》,这本书有2个作者。那么book_authors应该有2条记录

    它应该是这样的

    id book_id author_id
    1        3        1
    2        3        2
    View Code

    那么如何将这2条记录,插入进去呢?

    修改add视图函数,注意导入author类

    先插入一条记录

    book = Book.objects.create(title='python',price=122,pub_date="2012-12-12",publish_id=1)

    再获取2个作者

    xiao = Author.objects.filter(name="xiao").first()
    zhang = Author.objects.filter(name="zhang").first()

    最后插入2条记录,注意:下面2行代码是不能执行的,它是伪代码!

    book_authors.objects.create(book_id=book.id,author_id=xiao.id)
    book_authors.objects.create(book_id=book.id, author_id=zhang.id)

    上面2行代码表示在book_authors表中添加2条记录,只增加book_id和author_id。

    那么问题来了,book_authors这张表是用orm创建的
    但是orm的models.py里面找不到book_authors这张表的模型类。如果存在的话,那肯定没有问题的。
    因为第3张表,是在book类里面的authors属性,用ManyToManyField创建的
    因为一本书,对应的不止一个作者,所以不能直接赋值操作。

    add() 增加多个关系对象

    使用方法1:add(obj1, obj2, ...) 

    ORM提供了add方法,来添加多对多的关系表。

    def add(request):
        book = Book.objects.create(title='python',price=122,pub_date="2012-12-12",publish_id=1)
        xiao = Author.objects.filter(name="xiao").first()
        zhang = Author.objects.filter(name="zhang").first()
        book.authors.add(xiao,zhang)  # 添加2条数据,接收一个参数,就会产生一条记录
    
    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    注意:book.authors.add(xiao,zhang),相当于执行上面2句伪代码!

    它会自动获取2个对象的主键id,并插入到对应的字段中。

    刷新页面,查看book表,发现多了一条记录

    查看book_authors表,发现多2条数据

    如果需要为书籍绑定所有作者呢?

    author_list = Author.objects.all()
    book.authors.add(*author_list)

    上面2行代码,就搞定了,非常简洁!

    使用方法2:add(主键1, 主键2, ...) 

    下面这种写法,也是可以的。在html表单页面添加时,会用到此写法!

    book.authors.add(1,2)

    还有一种写法,是属于python的。*[1,2],表示打散。它相当于上面的写法

    book.authors.add(*[1,2])

    区别在于:add(1,2)这种写法,它是执行了2次,在book_authors表中插入2条记录。

    那么在不知道有多少数值的情况下,需要使用*[args1,args2]这种写法。

    注意:在html表单中的复选框中,它提交的数据是多个值,必须使用getlist方法获取,它是列表类型。

    因为不知道用户,到底会选择多少个选项。所以就需要使用这种打散写法!

    删除记录

    remove(obj1, obj2, ...) 去除多个关系对象

    举例:删除python这本书的xiao作者
    那么只需要删除book_authors表,id为1的这一条记录,就可以了

    但是,不能直接对这张表,直接删除。因为它是2个表的关联表。

     解除绑定的关系

    def add(request):
        book = Book.objects.filter(id=3).first()  # 先找到这本书
        xiao = Author.objects.filter(name="xiao").first()  # 再找到作者
        book.authors.remove(xiao)  # 解除绑定的关系
        return HttpResponse('添加成功')
    View Code

    刷新页面,查看book_authors表记录,发现作者没有了

    注意:这里可不是级联删除,book_authors并没有on_delete=models.CASCADE属性

    clear() 清理所有关系对象

    修改book_authors表记录,添加1条记录

    举例:将book_id等于3的所有的作者删除

    上面的例子,用remove,可以将一个删除。如果这本书,有5个作者呢?

     一个个remove?太累了!django提供了clear方法,可以清理所有关系对象。

    def add(request):
        book = Book.objects.filter(id=3).first()
        book.authors.clear()  # 清理所有关系对象
        return HttpResponse('添加成功')
    View Code

    刷新页面,再次查看book_authors表记录,发现已经空了!

    修改authordetail表,增加一条记录

    修改author表,增加一条记录

    修改book_authors表,增加3条数据

    set([obj1,obj2...])  先清空再设置

    set([obj1,obj2,...])  它接收多个值,可以一个,也可以多个。适用于后台网页修改操作!

    举例:

    python这本书目前有3个作者,将wang设置为这本书的唯一作者

    怎么做呢?将另外2个作者解除关系就可以了。

    def add(request):
        book = Book.objects.filter(id=3).first()  # 先找到书
        xiao = Author.objects.filter(name="xiao").first()  # 再找到作者
        zhang = Author.objects.filter(name="zhang").first()
        book.authors.remove(xiao,zhang)  # 解除绑定的关系
    
    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    但是这样将2个作者解除,太麻烦了。

    还有一种做法,先清空,再设置

    def add(request):
        book = Book.objects.filter(id=3).first()  # 先找到书
        book.authors.clear()  # 清理所有关系对象
        wang = Author.objects.filter(name="wang").first()
        book.authors.add(wang)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    django提示了set方法,直接合并了先清空再设置的操作

    它必须接收一个数组,因为可以接收多个值

    def add(request):
        book = Book.objects.filter(id=3).first()  # 先找到书
        wang = Author.objects.filter(name="wang").first()  # 再找作者
        book.authors.set([wang])  #先清空再设置
    
    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新页面,查看book_authors表记录,发现只有一条了

    总结:

    重点掌握create,add,remove,clear,set这五个方法!

    添加表记录:

      一对一和一对多,使用create方法。它有2种使用方法:

        1. create(字段名1=值1...)。适用于表单添加操作!注意,这里面的字段名是ORM创建表之后的的字段名

          比如: book类的publish属性,它是关联字段,ORM创建之后,字段名为publish_id

        2.create(模型类属性1=值1...)。比如book类的publish属性,它是关联字段。

          直接create(publish=obj1),注意,它接收一个model对象,对象包含了主键id

      多对多使用add方法。add用2种使用方法:

        1.add(obj1,obj2...) 它接收一个model对象,对象包含了主键id

        2.add(主键id1,主键id2...) 它接收一个主键id。适用于表单添加操作!

        还有一个python的打散语法,前面加一个*就可以了。比如*[1,2],它会依次调用前置方法,每次只取一个值。表单操作,会用到!

     删除记录:

      适用于一对一,一对多,多对一。

      remove(obj1, obj2, ...) 去除多个关系对象。它需要指定一个或者多个对象

      clear() 清理所有关系对象。不管现有的关系有多少,一律清空!

      set([obj1,obj2...]) 先清空再设置。不管现有的关系有多少,一律清空再设置。适用于网页后台修改操作

     

    基于对象的跨表查询(子查询)

    先来查询id为3的书籍,打印publish和authors是什么?

    def add(request):
        book = Book.objects.filter(id=3).first()
        print(book.publish)  # 查看publish属性
        print(book.authors)
        print(type(book.authors))  # 查看类型
        print(book.authors.all())  # 返回所有book的关联对象
        print(book.authors.all().values())  # 查看关联对象的值
    
    <span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新页面,查看控制台信息

    Publish object (1)
    app01.Author.None
    <class 'django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager'>
    <QuerySet [<Author: Author object (3)>]>
    <QuerySet [{'name': 'wang', 'age': 27, 'id': 3, 'ad_id': 3}]>
    View Code

    注意:book.authors不能直接print,否则返回的值是None。它是一个多对多的关系管理器,必须用all()才能取值。

    book.authors.all() 表示返回所有book的关联对象。注意:这里的book对象,是一个model对象,它是表示id为3的一条记录。从最后一条打印信息中,就可以看出来!

    修改book_authors表,添加2条记录

    再次刷新页面,查看控制台信息

    Publish object (1)
    app01.Author.None
    <class 'django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager'>
    <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>, <Author: Author object (3)>]>
    <QuerySet [{'name': 'xiao', 'id': 1, 'ad_id': 1, 'age': 25}, {'name': 'zhang', 'id': 2, 'ad_id': 2, 'age': 26}, {'name': 'wang', 'id': 3, 'ad_id': 3, 'age': 27}]>
    View Code

    注意最后一条信息,它返回了3个model对象。为什么会返回3条信息呢?

    它实际是执行了下面这句SQL

    SELECT
        author.id,
        author.name,
        author.age,
        author.ad_id
    FROM
        author
    INNER JOIN book_authors ON (
        author.id = book_authors.author_id
    )
    WHERE
        book_authors.book_id = 3
    LIMIT 21;
    View Code

    因为book的id为3,它先从关系表book_authors,查找book_id=3的记录。此时有3条记录!

    再和author表关联查询,找出3个作者的记录。所以最终结果就是author的3条记录!

    book.authors.all()是与这本书关联的作者对象queryset对象集合

    django有2个日期类型,一个是DateField(),它的格式是yyyy-mm-dd

    还有一个类型是DateTimeField(),它的格式是yyyy-mm-dd h:i:s。它是带时分秒的!

    python中的datetime

    举例:

    import datetime
    now = datetime.datetime.now()
    print(now)  # 当前时间
    print(now.today())  # 当前时间
    print(now.date())  # 日期
    print(now.time())  # 排除日期,取时分秒
    print(now.strftime("%Y-%m-%d %H:%I:%S"))  # 格式化时间
    
    delta = datetime.timedelta(days=3)  # 时间差
    print(delta)
    print(now+delta)  # 3天后
    print(now-delta)  # 3天后
    View Code

    输出:

    2018-06-29 20:59:02.741780
    2018-06-29 20:59:02.741781
    2018-06-29
    20:59:02.741780
    2018-06-29 20:08:02
    3 days, 0:00:00
    2018-07-02 20:59:02.741780
    2018-06-26 20:59:02.741780
    View Code

    一对多查询(Publish 与 Book)

    book_authors表添加2条数据

    举例:

    查询西游记这本书的出版社的名字

    普通写法

    先找出这本书,然后取出publish_id。在publish表中,通过publish_id找到对应记录。

    def add(request):
        book = Book.objects.filter(title="西游记").first()
        publish_id = book.publish_id
        publish = Publish.objects.filter(id=publish_id).first()
        print(publish.name)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,查看控制台,输出:

    榴莲出版社

    推荐写法:

    上面的步骤太麻烦了,下面使用简洁写法,2行就搞定了!

    def add(request):
        book = Book.objects.filter(title="西游记").first()
        print(book.publish.name)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    举例:查询西瓜出版社出版过的所有书籍的名称

    def add(request):
        publish = Publish.objects.filter(name="西瓜出版社").first()  # 先找出版社
        ret = Book.objects.filter(publish_id=publish.id).values("title")  # 再找书籍
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,查看控制台,效果同上

    上面写的太麻烦,下面来介绍正向查询和反向查询

    正向和反向,就看关键字段在哪里?
    如果是通过关联字段查询,就是正向。否则是反向!

    简单来说:正向,按照字段。反向,按照表名

    正向与反向查询

    正向查询:关联属性在book表中,所以book对象找出关联出版社对象,正向查询

    反向查询:关联属性在book表中,所以publish对象找出关联书籍,正向查询

        正向:按字段:publish
    book -----------> publish
         <----------- 
        反向:按表名小写_set() 例如:publish.obj.book_set()

    正向查询

    还是上面的例子:查询西瓜出版社出版过的所有书籍的名称

    简洁写法:

    def add(request):
        publish = Publish.objects.filter(name="西瓜出版社").first()  # 先找出版社
        # ret = Book.objects.filter(publish_id=publish.id).values("title")  # 再找书籍
        # print(ret)
        #正向查询--简洁写法
        ret = publish.book_set.all().values("title")
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,控制台输出:

    <QuerySet [{'title': '三国演义'}, {'title': 'python'}]>

    推荐使用简洁写法,为什么呢?因为如果表越来越多,那么SQL就非常复杂。使用简洁写法,就能避免!

    那么它是如何实现的呢?通过Book模型类的authors属性

    authors=models.ManyToManyField(to="Author")

    反向查询

    举例:查询与西瓜出版社关联的所有书籍的名字

    def add(request):
        publish = Publish.objects.filter(name="西瓜出版社").first()  # 先找出版社
        ret = publish.book_set.all().values("title")  # 再找书籍,过滤title
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,控制台输出:

    <QuerySet [{'title': '三国演义'}, {'title': 'python'}]>

    多对多查询 (Author 与 Book)

    正向查询:关联属性在book表中,所以book对象找出关联作者集合,正向查询

    反向查询:关联属性在book表中,所以author对象找出关联书籍,正向查询

    因为记录有多条,所以结尾要加.all()

        正向:按字段:authors.all()
    book -----------> author
         <----------- 
        反向:按表名小写_set().all() 例如:author.obj.book_set().all()

    正向查询

    举例:查询西游记这本书籍的所有作者的姓名和年龄

    def add(request):
        book = Book.objects.filter(title="西游记").first()  # 先找书籍
        ret = book.authors.all().values("name","age")  # 再找作者,过滤name和age
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,控制台输出:

    <QuerySet [{'age': 25, 'name': 'xiao'}]>

    反向查询

    举例:查询作者xiao出版过的所有书籍名称

    def add(request):
        xiao = Author.objects.filter(name="xiao").first()  # 先找作者
        ret = xiao.book_set.all().values("title")  # 再找书籍,过滤title
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,控制台输出:

    <QuerySet [{'title': 'python'}, {'title': '西游记'}]>

    一对一查询(Author 与 AuthorDetail)

    正向查询:关联属性在author表中,所以author对象找出关联作者详细信息对象,正向查询

    反向查询:关联属性在book表中,所以author对象找出关联书籍,正向查询

    因为记录只有一条,所以直接.ad就可以了。ad是关联字段

        正向:按字段:.ad
    author -----------> authordetail
         <----------- 
        反向:按表名小写 例如:authordetail_obj.author

    正向查询

    举例:查询xiao的女朋友的名字

    def add(request):
        xiao = Author.objects.filter(name="xiao").first()  # 先找作者
        ret = xiao.ad.gf  # 再找女朋友
        print(ret)
    
    </span><span style="color: #0000ff;">return</span> HttpResponse(<span style="color: #800000;">'</span><span style="color: #800000;">添加成功</span><span style="color: #800000;">'</span>)</pre>
    
    View Code

    刷新网页,控制台输出:

    赵丽颖

    反向查询

    举例:查询手机号为112的作者名字

    def add(request):
        phone = AuthorDetail.objects.filter(tel="112").first()  # 先找号码
        ret = phone.author.name  # 再找作者的名字
        print(ret)
    View Code

    刷新网页,控制台输出:

    wang

    周末作业

    基于多表的图书管理系统

    注意:出版社和作者,是从数据库中读取的。

    作业是复选框,可以选择多个

     编辑页面,作者一栏的灰色背景。表示现有绑定的作者!

    它是选择状,使用selected属性

    提示:

    视图函数接收复选框的值,需要使用request.POST.getlist()。使用get只能获取一个值!

    答案

    修改urls.py,添加路径

    from django.contrib import admin
    from django.urls import path,re_path
    

    from book import views
    urlpatterns
    = [
    path(
    'admin/', admin.site.urls),
    path(
    '', views.index),
    path(
    'index/', views.index),
    path(
    'books/add/', views.add),
    path(
    'books/manage/', views.manage),
    re_path(
    'books/delete/(?P<id>d+)', views.delete),
    re_path(
    'books/modify/(?P<id>d+)', views.modify),
    ]

    View Code

    修改settings.py

    注册app

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'book',
    ]
    View Code

    指定模板路径

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    View Code

    默认使用sqlite3数据库,有需要的使用其他数据库的,自行更改

    指定静态资源路径

    STATIC_URL = '/static/'
    STATICFILES_DIRS=[
        os.path.join(BASE_DIR,"static")
    ]
    View Code

    手动创建templates和static目录。

    在static目录创建css目录,下载bootstrap 3.3.7的数据包。将将bootstrap.min.css放到css目录

    修改models.py

    from django.db import models
    

    # Create your models here.
    class Book(models.Model):
    title
    =models.CharField(max_length=32,unique=True)
    price
    =models.DecimalField(max_digits=8,decimal_places=2,null=True)
    pub_date
    =models.DateField()
    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE)
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建关系表book_authors
    authors=models.ManyToManyField(to="Author")

    class Publish(models.Model):
    name
    =models.CharField(max_length=32)
    email
    =models.CharField(max_length=32)
    addr
    =models.CharField(max_length=32)

    class Author(models.Model):
    name
    =models.CharField(max_length=32)
    age
    =models.IntegerField()
    # 与AuthorDetail建立一对一的关系
    # ad=models.ForeignKey(to="AuthorDetail",to_field="id",on_delete=models.CASCADE,unique=True)
    ad=models.OneToOneField(to="AuthorDetail",to_field="id",on_delete=models.CASCADE,)

    class AuthorDetail(models.Model):
    gf
    =models.CharField(max_length=32)
    tel
    =models.CharField(max_length=32)

    View Code

    使用2个命令生成表

    python manage.py makemigrations
    python manage.py migrate

    使用navicat打开sqlite数据库,5个表,添加初始数据

    注意修改应用名,因为每个人的应用名不一样!

    下面是sql语句:

    #作者详情表
    INSERT INTO book_authordetail (`id`, `gf`, `tel`) VALUES (1, '赵丽颖',110);
    INSERT INTO book_authordetail (`id`, `gf`, `tel`) VALUES (2, '刘诗诗',111);
    INSERT INTO book_authordetail (`id`, `gf`, `tel`) VALUES (3, '唐嫣',112);
    

    #作者表

    INSERT INTO book_author (id, name, age, ad_id) VALUES (
    1, 'xiao',25,1);
    INSERT INTO book_author (id, name, age, ad_id) VALUES (
    2, 'zhang',26,2);
    INSERT INTO book_author (id, name, age, ad_id) VALUES (
    3, 'wang',27,3);

    #出版社表

    INSERT INTO book_publish (id, name, email, addr) VALUES (
    1, '人民教育出版社', 'rm@qq.com', '北京');
    INSERT INTO book_publish (id, name, email, addr) VALUES (
    2, '中国农业出版社', 'zg@qq.com', '北京');
    INSERT INTO book_publish (id, name, email, addr) VALUES (
    3, '中国林业出版社', 'ly@qq.com', '云南');

    #书籍表
    INSERT INTO book_book (id, title, price, pub_date, publish_id) VALUES (1, '西游记',2, '1501-01-23',1);
    INSERT INTO book_book (id, title, price, pub_date, publish_id) VALUES (
    2, '红楼梦',3, '1715-02-13',2);
    INSERT INTO book_book (id, title, price, pub_date, publish_id) VALUES (
    3, '三国演义',4, '1330-03-25',3);

    #书籍和作者关系表
    INSERT INTO book_book_authors (id, book_id, author_id) VALUES (1,1,1);
    INSERT INTO book_book_authors (id, book_id, author_id) VALUES (
    2,2,2);
    INSERT INTO book_book_authors (id, book_id, author_id) VALUES (
    3,3,3);

    View Code

    修改views.py

    from django.shortcuts import render,HttpResponse
    #导入4个表模型
    from book.models import Book,Publish,Author,AuthorDetail
    

    # Create your views here.
    def index(request): #首页
    ret = Book.objects.all().exists() # 判断表是否有记录
    if ret:
    book_list
    = Book.objects.all() # 查询表的所有记录
    return render(request, "index.html", {"book_list": book_list})

    </span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
        hint </span>= <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("没有书籍,请添加书籍");window.location.href="/books/add"&lt;/script&gt;</span><span style="color: #800000;">'</span>
        <span style="color: #0000ff;">return</span> HttpResponse(hint)  <span style="color: #008000;">#</span><span style="color: #008000;"> js跳转到添加页面</span>
    

    def add(request): # 添加
    if request.method=="POST":
    # print(request.POST)
    title=request.POST.get("title")
    the_book
    = Book.objects.filter(title=title).exists()
    if the_book:
    hint
    = '<script>alert("书籍已存在!不能重复添加");window.location.href="/books/add/"</script>'
    return HttpResponse(hint) # js跳转到添加页面
    else:
    price
    =request.POST.get("price")
    pub_date
    =request.POST.get("pub_date")
    publish_id
    =request.POST.get("publish_id")
    author_id
    =request.POST.getlist("author_id") # 返回列表
    print(title,price,pub_date,publish_id,author_id)
    #先插入书籍
    book = Book.objects.create(title=title, price=price, pub_date=pub_date, publish_id=publish_id)
    #再插入作者
    book.authors.add(*author_id)

            hint </span>= <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("添加成功");window.location.href="/index/"&lt;/script&gt;</span><span style="color: #800000;">'</span>
            <span style="color: #0000ff;">return</span> HttpResponse(hint)  <span style="color: #008000;">#</span><span style="color: #008000;"> js跳转到首页</span>
    
    <span style="color: #008000;">#</span><span style="color: #008000;">读取所有出版社,过滤出id和name</span>
    publish_list = Publish.objects.all().values(<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    </span><span style="color: #008000;">#</span><span style="color: #008000;"> 读取所有作者,过滤出id和name</span>
    author_list = Author.objects.all().values(<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    
    </span><span style="color: #0000ff;">return</span> render(request, <span style="color: #800000;">"</span><span style="color: #800000;">add.html</span><span style="color: #800000;">"</span>, {<span style="color: #800000;">"</span><span style="color: #800000;">publish_list</span><span style="color: #800000;">"</span>: publish_list,<span style="color: #800000;">"</span><span style="color: #800000;">author_list</span><span style="color: #800000;">"</span><span style="color: #000000;">:author_list})
    

    def delete(request,id): # 删除
    # 先删除关系表中的作者
    book_ad = Book.objects.filter(id=id).first()
    book_ad.authors.clear()

    </span><span style="color: #008000;">#</span><span style="color: #008000;"> 再删除书籍</span>
    ret = Book.objects.filter(id=id).delete() <span style="color: #008000;">#</span><span style="color: #008000;"> 返回元组</span>
    <span style="color: #0000ff;">print</span><span style="color: #000000;">(ret)
    
    </span><span style="color: #0000ff;">if</span> ret[0]:  <span style="color: #008000;">#</span><span style="color: #008000;"> 取值为1的情况下</span>
        hint = <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("删除成功");window.location.href="/index/"&lt;/script&gt;</span><span style="color: #800000;">'</span>
        <span style="color: #0000ff;">return</span><span style="color: #000000;"> HttpResponse(hint)
    </span><span style="color: #0000ff;">else</span>:  <span style="color: #008000;">#</span><span style="color: #008000;"> 取值为0的情况下</span>
        hint = <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("删除失败");window.location.href="/index/"&lt;/script&gt;</span><span style="color: #800000;">'</span>
        <span style="color: #0000ff;">return</span><span style="color: #000000;"> HttpResponse(hint)
    

    def manage(request): # 管理页面
    ret = Book.objects.all().exists()
    if ret:
    book_list
    = Book.objects.all()
    #加载管理页面
    return render(request, "manage.html", {"book_list": book_list})
    else:
    hint
    = '<script>alert("没有书籍,请添加书籍");window.location.href="/books/add"</script>'
    return HttpResponse(hint)

    def modify(request,id): # 修改
    if request.method == "POST":
    title
    = request.POST.get("title")
    price
    = request.POST.get("price")
    pub_date
    = request.POST.get("pub_date")
    publish_id
    = request.POST.get("publish_id")
    author_id
    = request.POST.getlist("author_id") # 返回列表

        <span style="color: #008000;">#</span><span style="color: #008000;"> 先修改书籍</span>
        ret = Book.objects.filter(id=id).update(title=title, price=price, pub_date=pub_date, publish_id=<span style="color: #000000;">publish_id)
        </span><span style="color: #008000;">#</span><span style="color: #008000;"> 获取当前书籍</span>
        book_ad = Book.objects.filter(id=<span style="color: #000000;">id).first()
        book_ad.authors.set(author_id)  </span><span style="color: #008000;">#</span><span style="color: #008000;"> 先清空再设置</span>
    
        <span style="color: #0000ff;">if</span> ret:  <span style="color: #008000;">#</span><span style="color: #008000;"> 判断返回值为1</span>
            hint = <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("修改成功");window.location.href="/index/"&lt;/script&gt;</span><span style="color: #800000;">'</span>
            <span style="color: #0000ff;">return</span> HttpResponse(hint)  <span style="color: #008000;">#</span><span style="color: #008000;"> js跳转</span>
        <span style="color: #0000ff;">else</span>:  <span style="color: #008000;">#</span><span style="color: #008000;"> 返回为0</span>
            hint = <span style="color: #800000;">'</span><span style="color: #800000;">&lt;script&gt;alert("修改失败");window.location.href="/index/"&lt;/script&gt;</span><span style="color: #800000;">'</span>
            <span style="color: #0000ff;">return</span> HttpResponse(hint)  <span style="color: #008000;">#</span><span style="color: #008000;"> js跳转</span>
    
    book = Book.objects.get(id=id) # 默认获取id值 # print(book)
    <span style="color: #008000;">#</span><span style="color: #008000;"> 读取所有出版社,过滤出id和name</span>
    publish_list = Publish.objects.all().values(<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    </span><span style="color: #008000;">#</span><span style="color: #008000;"> 读取所有作者,过滤出id和name</span>
    author_list = Author.objects.all().values(<span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    the_author </span>= []  <span style="color: #008000;">#</span><span style="color: #008000;"> 当前书籍的作者</span>
    <span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span><span style="color: #000000;"> book.authors.all():
        the_author.append(i.name)  </span><span style="color: #008000;">#</span><span style="color: #008000;"> 最加到列表中</span>
    <span style="color: #0000ff;">print</span><span style="color: #000000;">(the_author)
    
    </span><span style="color: #0000ff;">return</span> render(request, <span style="color: #800000;">"</span><span style="color: #800000;">modify.html</span><span style="color: #800000;">"</span>, {<span style="color: #800000;">"</span><span style="color: #800000;">book</span><span style="color: #800000;">"</span>:book,<span style="color: #800000;">"</span><span style="color: #800000;">publish_list</span><span style="color: #800000;">"</span>: publish_list, <span style="color: #800000;">"</span><span style="color: #800000;">author_list</span><span style="color: #800000;">"</span>: author_list,<span style="color: #800000;">"</span><span style="color: #800000;">the_author</span><span style="color: #800000;">"</span>:the_author})</pre>
    
    View Code

    在templates目录新建几个html文件

    base.html,这个是所有html的母版文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        {% block title %}
            <title>title</title>
        {% endblock title %}
        {#bootstrap,版本为3.3.7#}
        <link rel="stylesheet" href="/static/css/bootstrap.min.css">
        {#美化复选框#}
        <link rel="stylesheet" href="https://cdn.bootcss.com/awesome-bootstrap-checkbox/0.3.7/awesome-bootstrap-checkbox.css">
        <link href="http://cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
        .header {
             </span>100%<span style="color: #000000;">;
            height: 60px;
            background</span>-color: <span style="color: #008000;">#</span><span style="color: #008000;">369;</span>
    

    }

        .title {
    
            line</span>-<span style="color: #000000;">height: 60px;
            color: white;
            font</span>-weight: 100<span style="color: #000000;">;
            margin</span>-<span style="color: #000000;">left: 20px;
            font</span>-<span style="color: #000000;">size: 20px;
        }
    
        .container {
            margin</span>-<span style="color: #000000;">top: 20px;
        }
    
        .table th, .table td {
            text</span>-<span style="color: #000000;">align: center;
            vertical</span>-<span style="color: #000000;">align: middle !important;
        }
    </span>&lt;/style&gt;
    

    </head>
    <body>

    <div class="header">
    <p class="title">
    图书管理系统
    </p>
    </div>

    <div class="container">
    <div class="row">
    <div class="col-md-3">
    <div class="panel panel-danger">
    <div class="panel-heading"><a href="/index/">查看书籍</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-success">
    <div class="panel-heading"><a href="/books/add/">添加书籍</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    <div class="panel panel-warning">
    <div class="panel-heading"><a href="/books/manage/">管理书籍</a></div>
    <div class="panel-body">
    Panel content
    </div>
    </div>
    </div>
    <div class="col-md-9">
    {
    % block content %}

            {</span>% endblock %<span style="color: #000000;">}
        </span>&lt;/div&gt;
    &lt;/div&gt;
    

    </div>

    </body>
    </html>

    View Code

    index.html,首页

    {% extends 'base.html' %}
    

    {% block title %}

    </span>&lt;title&gt;查看书籍&lt;/title&gt;<span style="color: #000000;">
    

    {% endblock title %}

    {% block content %}
    <h3>查看书籍</h3>
    <table class="table table-hover table-striped ">
    <thead>
    <tr>
    <th>编号</th>
    <th>书籍名称</th>
    <th>价格</th>
    <th>出版日期</th>
    <th>出版社</th>
    <th>作者</th>
    </tr>
    </thead>
    <tbody>
    {
    #遍历所有书籍#}
    {% for book in book_list %}
    <tr>
    <td>{{ book.id }}</td>
    <td>{{ book.title }}</td>
    <td>{{ book.price }}</td>
    <td>{{ book.pub_date|date:"Y-m-d" }}</td>
    <td>{{ book.publish.name }}</td>
    <td>
    {
    #遍历所有书籍相关的作者#}
    {% for j in book.authors.all %}
    {
    #使用forloop.last判断,如果如果是最后一个,不增加逗号#}
    {{ j.name }}{% if not forloop.last %},{% endif %}
    {
    % endfor %}
    </td>

            &lt;/tr&gt;<span style="color: #000000;">
        {</span>% endfor %<span style="color: #000000;">}
    
        </span>&lt;/tbody&gt;
    &lt;/table&gt;<span style="color: #000000;">
    

    {% endblock content %}

    View Code

    add.html,添加页面

    {% extends 'base.html' %}
    

    {% block title %}

    </span>&lt;title&gt;添加书籍&lt;/title&gt;<span style="color: #000000;">
    

    {% endblock title %}

    {% block content %}
    <h3>添加书籍</h3>
    <form action="" method="post">
    {
    % csrf_token %}
    <div class="form-group">
    <label for="">书籍名称</label>
    <input type="text" name="title" class="form-control">
    </div>
    <div class="form-group">
    <label for="">价格</label>
    <input type="text" name="price" class="form-control">
    </div>
    <div class="form-group">
    <label for="">出版日期</label>
    <input type="date" name="pub_date" class="form-control">
    </div>
    <div class="form-group">
    <label for="">出版社</label>
    <select name="publish_id" id="" class="form-control">
    {
    #使用for循环遍历所有出版社#}
    {% for p in publish_list %}
    {
    #由于表关系是通过id关联的,所以value值必须是id#}
    <option value="{{ p.id }}">{{ p.name }}</option>
    {
    % endfor %}
    </select>

        &lt;/div&gt;
        &lt;div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>&gt;
            &lt;label <span style="color: #0000ff;">for</span>=<span style="color: #800000;">""</span>&gt;作者&lt;/label&gt;
            &lt;ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
                {</span><span style="color: #008000;">#</span><span style="color: #008000;">使用for循环遍历所有作者#}</span>
                {% <span style="color: #0000ff;">for</span> author <span style="color: #0000ff;">in</span> author_list %<span style="color: #000000;">}
                    </span>&lt;li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>&gt;
                        &lt;div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox checkbox-success </span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
                            {</span><span style="color: #008000;">#</span><span style="color: #008000;">由于表关系是通过id关联的,所以value值必须是id#}</span>
                            &lt;input <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">styled</span><span style="color: #800000;">"</span> type=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">author_id</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">{{ author.id }}</span><span style="color: #800000;">"</span>&gt;
                            &lt;label <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox-inline</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
                                {{ author.name }}
                            </span>&lt;/label&gt;
                        &lt;/div&gt;
                    &lt;/li&gt;<span style="color: #000000;">
                {</span>% endfor %<span style="color: #000000;">}
            </span>&lt;/ul&gt;
    
        &lt;/div&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-success pull-right</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">添加</span><span style="color: #800000;">"</span>&gt;
    &lt;/form&gt;<span style="color: #000000;">
    

    {% endblock content %}

    View Code

    manage.html,管理页面,用来删除和修改的

    {% extends 'base.html' %}
    

    {% block title %}

    </span>&lt;title&gt;管理书籍&lt;/title&gt;<span style="color: #000000;">
    

    {% endblock title %}

    {% block content %}
    <h3>管理书籍</h3>
    <table class="table table-hover table-striped ">
    <thead>
    <tr>
    <th>编号</th>
    <th>书籍名称</th>
    <th>价格</th>
    <th>出版日期</th>
    <th>出版社</th>
    <th>作者</th>
    <th>删除</th>
    <th>编辑</th>
    </tr>
    </thead>
    <tbody>
    {
    % for book in book_list %}
    <tr>
    <td>{{ book.id }}</td>
    <td>{{ book.title }}</td>
    <td>{{ book.price }}</td>
    <td>{{ book.pub_date|date:"Y-m-d" }}</td>
    <td>{{ book.publish.name }}</td>
    <td>
    {
    #遍历所有书籍相关的作者#}
    {% for j in book.authors.all %}
    {
    #使用forloop.last判断,如果如果是最后一个,不增加逗号#}
    {{ j.name }}{% if not forloop.last %},{% endif %}
    {
    % endfor %}
    </td>
    <td>
    {
    #由于表关系是通过id关联的,所以参数必须是id#}
    <a href="/books/delete/{{ book.id }}">
    <button type="button" class="btn btn-danger" data-toggle="modal" id="modelBtn">删除</button>
    </a>
    </td>
    <td>
    <a href="/books/modify/{{ book.id }}">
    <button type="button" class="btn btn-success" data-toggle="modal">编辑</button>
    </a>
    </td>
    </tr>
    {
    % endfor %}

        </span>&lt;/tbody&gt;
    &lt;/table&gt;<span style="color: #000000;">
    

    {% endblock content %}

    View Code

    modify.html,修改页面

    {% extends 'base.html' %}
    

    {% block title %}

    </span>&lt;title&gt;修改书籍&lt;/title&gt;<span style="color: #000000;">
    

    {% endblock title %}

    {% block content %}
    <h3>修改书籍</h3>
    <form action="" method="post">
    {
    % csrf_token %}
    <div class="form-group">
    <label for="">书籍名称</label>
    <input type="text" name="title" class="form-control" value="{{ book.title }}">
    </div>
    <div class="form-group">
    <label for="">价格</label>
    <input type="text" name="price" class="form-control" value="{{ book.price }}">
    </div>
    <div class="form-group">
    <label for="">出版日期</label>
    <input type="date" name="pub_date" class="form-control" value="{{ book.pub_date|date:"Y-m-d" }}">
    </div>
    <div class="form-group">
    <label for="">出版社</label>
    <select name="publish_id" id="" class="form-control">
    {
    #遍历所有出版社#}
    {% for p in publish_list %}
    {
    #判断当前书籍的出版社id等于出版社表的id时#}
    {% if book.publish_id == p.id %}
    {
    #添加选中状态selected="selected"#}
    {#由于表关系是通过id关联的,所以value值必须是id#}
    <option value="{{ p.id }}" selected="selected">{{ p.name }}</option>
    {
    % else %}
    <option value="{{ p.id }}">{{ p.name }}</option>
    {
    % endif %}

                {</span>% endfor %<span style="color: #000000;">}
            </span>&lt;/select&gt;
        &lt;/div&gt;
        &lt;div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">form-group</span><span style="color: #800000;">"</span>&gt;
            &lt;label <span style="color: #0000ff;">for</span>=<span style="color: #800000;">""</span>&gt;作者&lt;/label&gt;
            &lt;ul <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group</span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
                {</span>% <span style="color: #0000ff;">for</span> author <span style="color: #0000ff;">in</span> author_list %<span style="color: #000000;">}
                    </span>&lt;li <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">list-group-item</span><span style="color: #800000;">"</span>&gt;
                        &lt;div <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox checkbox-success </span><span style="color: #800000;">"</span>&gt;<span style="color: #000000;">
                            {</span><span style="color: #008000;">#</span><span style="color: #008000;">判断作者的名字在当前书籍作者列表中#}</span>
                            {% <span style="color: #0000ff;">if</span> author.name <span style="color: #0000ff;">in</span> the_author %<span style="color: #000000;">}
                                {</span><span style="color: #008000;">#</span><span style="color: #008000;">添加选中状态checked="checked"#}</span>
                                {<span style="color: #008000;">#</span><span style="color: #008000;">由于表关系是通过id关联的,所以value值必须是id#}</span>
                                &lt;input <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">styled</span><span style="color: #800000;">"</span> type=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox</span><span style="color: #800000;">"</span> checked=<span style="color: #800000;">"</span><span style="color: #800000;">checked</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">author_id</span><span style="color: #800000;">"</span><span style="color: #000000;">
                                       value</span>=<span style="color: #800000;">"</span><span style="color: #800000;">{{ author.id }}</span><span style="color: #800000;">"</span>&gt;
                                &lt;label <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox-inline</span><span style="color: #800000;">"</span>&gt;{{ author.name }}&lt;/label&gt;<span style="color: #000000;">
                            {</span>% <span style="color: #0000ff;">else</span> %<span style="color: #000000;">}
                                </span>&lt;input <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">styled</span><span style="color: #800000;">"</span> type=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox</span><span style="color: #800000;">"</span> name=<span style="color: #800000;">"</span><span style="color: #800000;">author_id</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">{{ author.id }}</span><span style="color: #800000;">"</span>&gt;
                                &lt;label <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">checkbox-inline</span><span style="color: #800000;">"</span>&gt;{{ author.name }}&lt;/label&gt;<span style="color: #000000;">
                            {</span>% endif %<span style="color: #000000;">}
                        </span>&lt;/div&gt;
                    &lt;/li&gt;<span style="color: #000000;">
                {</span>% endfor %<span style="color: #000000;">}
            </span>&lt;/ul&gt;
    
        &lt;/div&gt;
        &lt;input type=<span style="color: #800000;">"</span><span style="color: #800000;">submit</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">class</span>=<span style="color: #800000;">"</span><span style="color: #800000;">btn btn-default pull-right</span><span style="color: #800000;">"</span> value=<span style="color: #800000;">"</span><span style="color: #800000;">修改</span><span style="color: #800000;">"</span>&gt;
    &lt;/form&gt;<span style="color: #000000;">
    

    {% endblock content %}

    View Code

    项目文件结构如下:

    复制代码
    bms_mto
    ├── bms_mto
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── book
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── db.sqlite3
    ├── manage.py
    ├── static
    │   └── css
    │       ├── bootstrap.min.css
    └── templates
        ├── add.html
        ├── base.html
        ├── index.html
        ├── manage.html
        └── modify.html
    复制代码

     启动项目访问首页:http://127.0.0.1:8000/

    点击左侧的添加书籍

    添加一本书,选择2个作者

    提示添加成功

     首页就会多一本书籍

     

     点击编辑按钮

     修改价格,增加一个作者

    提示修改成功

     首页的书籍,价格和作者更新过来了

     点击删除

    提示删除成功

    首页少了一条数据


    参考资料:

    Django 基础教程

    转载声明:
    作者:肖祥
    出处: https://www.cnblogs.com/xiao987334176/

  • 相关阅读:
    Java获取Linux系统cpu使用率
    jsoup 提取 html 中的所有链接、图片和媒体
    使用Spring定时任务并且通过AOP监控任务执行情况
    MySQL导出数据库、数据库表结构、存储过程及函数【用】
    linux下部署一个JavaEE项目的简单步骤
    MySQL 错误日志(Error Log)
    linux下程序JDBC连接不到mysql数据库
    linux下mysql登录报错“Access denied for user 'root'@'localhost' (using password: YES”)的处理方法
    Spring Boot的核心
    项目中菜单折叠问题
  • 原文地址:https://www.cnblogs.com/bqwzx/p/10160031.html
Copyright © 2011-2022 走看看