• Django_综合案例(三)


    案例效果如下:

    1. 打开 /booktest/显示书籍列表
    2. 点击新增,增加一条数据
    3. 点击删除,删除一条数据
    4. 点击查看,跳转英雄信息界面

    1.定义模型类

    打开booktest/models.py文件,定义模型类如下

    from django.db import models
    
    # Create your models here.
    
    
    # 定义书籍模型类
    class BookInfo(models.Model):
        btitle = models.CharField(max_length=20)    # 书籍名称
        bpub_date = models.DateField()              # 发布日期
        bread = models.IntegerField(default=0)      # 阅读量
        bcomment = models.IntegerField(default=0)   # 评论量
        isDelete = models.BooleanField(default=False)   # 逻辑删除
    
    
    # 定义英雄模型类
    class HeroInfo(models.Model):
        hname = models.CharField(max_length=20)     # 英雄姓名
        hgender = models.BooleanField(default=True)     # 英雄性别,True为男
        hcomment = models.CharField(max_length=200)     # 英雄描述信息
        hbook = models.ForeignKey(BookInfo, on_delete=models.DO_NOTHING)       # 英雄与书籍关系为一对多

    2.迁移

    python manage.py makemigrations
    python manage.py migrate

    表bookinfo结构如下:

    注意:默认值并不在数据库层面生效,而是在django创建对象时生效。

    表booktest_heroinfo结构如下:

    注意:Django框架会根据关系属性生成一个关系字段,并创建外键约束。

    3.导入测试数据

    在数据库命令行中,复制如下语句执行,向booktest_bookinfo和booktest_heroinfo表中插入测试数据:

    insert into booktest_bookinfo(id,btitle,bpub_date,bread,bcomment,isDelete) values
    (1,'射雕英雄传','1980-5-1',12,34,0),
    (2,'天龙八部','1986-7-24',36,40,0),
    (3,'笑傲江湖','1995-12-24',20,80,0),
    (4,'雪山飞狐','1987-11-11',58,24,0);
    
    
    insert into booktest_heroinfo(hname,hgender,hbook_id,hcomment) values
    ('郭靖',1,1,'左右互搏'),
    ('黄蓉',0,1,'打狗棍法'),
    ('黄药师',1,1,'弹指神通'),
    ('欧阳锋',1,1,'蛤蟆功'),
    ('梅超风',0,1,'九阴白骨爪'),
    ('乔峰',1,2,'降龙十八掌'),
    ('段誉',1,2,'六脉神剑'),
    ('虚竹',1,2,'天山六阳掌'),
    ('王语嫣',0,2,'神仙姐姐'),
    ('令狐冲',1,3,'独孤九剑'),
    ('任盈盈',0,3,'弹琴'),
    ('岳不群',1,3,'华山剑法'),
    ('东方不败',0,3,'葵花宝典'),
    ('胡斐',1,4,'胡家刀法'),
    ('苗若兰',0,4,'黄衣'),
    ('程灵素',0,4,'医术'),
    ('袁紫衣',0,4,'六合拳');

    4.定义视图

    打开booktest/views.py文件,定义视图代码如下:

    import datetime
    from django.shortcuts import render, redirect, get_object_or_404
    from booktest.models import BookInfo, HeroInfo
    from django.urls import reverse
    from django.http import HttpResponse, Http404
    
    
    # 查看所有书籍
    def index(request):
        books = BookInfo.objects.all()
        context = {'title': '书籍列表', 'books': books}
        return render(request, 'booktest/index.html', context)
    
    
    # 新增书籍
    def create(request):
        book = BookInfo(btitle="流星蝴蝶剑1", bpub_date=datetime.date(1995, 12, 30), bread=2, bcomment=1)  # django的类属性值可以在实例化时修改
        book.save()
        book = BookInfo.objects.create(btitle="流星蝴蝶剑2", bpub_date=datetime.date(1995, 12, 30), bread=2, bcomment=1)
        book.save()
        book = BookInfo()
        book.btitle = "流星蝴蝶剑3"
        book.bpub_date = datetime.date(1995, 12, 30)
        book.bread = 2
        book.bcomment=1
        book.save()
        # return redirect("/booktest/")
        return redirect(reverse("booktest:index"))      # 重定向的界面若需要传个book.id参数时reverse('booktest:index', args=(book.id,))
    
    
    # 删除书籍
    def delete(request, bid):
        # try:
        #     book = BookInfo.objects.get(id=int(bid))
        #     book.delete()
        #     return redirect("/booktest/index")
        # except:
        #     raise Http404("书籍不存在")
    
        # book = get_object_or_404(BookInfo, id=int(bid), )
        # pk就是primary key的缩写,model中都是有的主键,model的主键名称默认为id,所以大部分时候我们可以认为pk和id是完全一样的。
        # get_object_or_404() 为快捷函数,不能自定义404显示信息
        book = get_object_or_404(BookInfo, pk=int(bid), )
        book.delete()
        return redirect("/booktest/")
    
    
    # 查看英雄信息
    def hero_info(request, bid):
        heros = HeroInfo.objects.filter(hbook_id=int(bid))
        for hero in heros:
            if hero.hgender:
                hero.hgender = ""
            else:
                hero.hgender = ""
        context = {'title': '英雄信息', 'heros': heros}
        return render(request, "booktest/heroInfo.html", context)

    redirect方法是在执行完代码后,将界面重定向到index界面,使用时需要import导入

    5.配置url

    打开test1/urls.py文件,配置url如下:

    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('booktest/', include('booktest.urls')),    # booktest/ 可以为空白
    ]

    在booktest应用下创建urls.py文件,代码如下:

    from django.urls import path
    from django.urls import re_path
    
    from booktest import views
    
    urlpatterns = [
        # ex: /booktest/    # 调用index视图函数
        path('', views.index, name='index'),
    
        # ex: /booktest/create  # 调用create视图函数
        path('create', views.create),
    
        # ex: /booktest/delete/1
        # re_path('delete/(d+)', views.delete),   # 在path中使用正则时需要导入re_path方法
        path('delete/<int:bid>', views.delete, name='delete'),     # bid为视图函数的的形参名
    
        path('search/<int:bid>', views.hero_info, name='search')
    ]

    注意:

      1、正则分组匹配的值可以当做视图函数的参数被引用。

      2、<int:bid>中的bid为视图函数  def hero_info(request, bid) 中的bid

    6.创建模板

    打开test1/settings.py文件,配置模板查找目录TEMPLATES的DIRS。

    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',
                ],
            },
        },
    ]

    在templates/booktest/ 目录下创建index.html和heroInfo.html文件。

     

    index.html模板代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>图书列表</title>
        <style>
            body {background-color: #efefef;}
            td {text-align: center;}
        </style>
    </head>
    <body>
    <h1>{{title}}</h1>
    <a href="/booktest/create">新增</a>
    <table width="500px">
        <tr>
            <th>书籍名称</th>
            <th>发布日期</th>
            <th>阅读量</th>
            <th>评论量</th>
            <th>操作</th>
        </tr>
    
    {%for book in books%}
        <tr>
            <td>{{book.btitle}}</td>
            <td>{{book.bpub_date}}</td>
            <td>{{book.bread}}</td>
            <td>{{book.bcomment}}</td>
            <td>
                <a href="/booktest/delete/{{book.id}}">删除</a>
                <a href="/booktest/search/{{book.id}}">查看英雄</a>
            </td>
        </tr>
    {%endfor%}
    
    </table>
    </body>
    </html>

    heroInfo.html模板代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>英雄信息</title>
    </head>
    <body>
    <h1>{{title}}</h1>
        {% for hero in heros %}
            <li> {{ hero.hname }},{{ hero.hgender }},{{ hero.hcomment }}</li>
        {% endfor %}
    </body>
    </html>

    7.运行

    运行服务器。

    python manage.py runserver 9000

     

  • 相关阅读:
    [转]Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#)
    [转]OAuth 2.0
    SpringMVC之七:SpringMVC中使用Interceptor拦截器
    多数据源问题--Spring+Ibatis 访问多个数据源(非分布式事务)
    读写分离
    SVN中检出(check out) 和 导出(export) 的区别
    Hbase之三:Hbase Shell使用入门
    hadoop之一:概念和整体架构
    Twitter Storm如何保证消息不丢失
    Twitter Storm: storm的一些常见模式
  • 原文地址:https://www.cnblogs.com/testlearn/p/13897597.html
Copyright © 2020-2023  润新知