Django之聚合查询、分组查询、查询优化以及F、Q查询

目  录

  • 聚合查询

  • 分组查询

  • F、Q查询

  • 自定义char字段

  • 查询优化(*****面试重点)

  • Django ORM中的事务操作

  • 案例--图书管理系统

前言:以下操作的数据库表模型如下(app01下的models.py):

from django.db import models

# Create your models here.


#  自定义char类型
class MyCharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)'%self.max_length
'''
建表时,要注意先将主表建好,在建立表关系
'''
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_date = models.DateField()

    maichu = models.IntegerField(default=1000)
    kucun = models.IntegerField(default=1000)

    #  书籍和出版社是一对多的关系,外键建在多的一方
    publish = models.ForeignKey(to='Publish')

    #  书籍和作者是多对多的关系,需要第三张表
    authors = models.ManyToManyField(to='Author')


    def __str__(self):
        return self.title


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


    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    hobby = MyCharField(max_length=32,default='read')

    # 作者和作者详情是一对一的关系,外键建立在查询频率高的一方
    author_detail = models.OneToOneField(to='AuthorDetail')


    def __str__(self):
        return self.name


class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=64)



    def __str__(self):
        return self.addr
models.py

一、聚合查询

聚合函数:在已经搭建好测试环境的tesy.py中导入聚合函数

from django.db.models import Max,Min,Sum,Count,Avg
 """
    聚合查询
    
    关键字:aggregate
    """
    from django.db.models import Max,Min,Count,Sum,Avg
    # 统计所有书平均价格
    # res = models.Book.objects.all().aggregate(Avg('price'))
    # res1 = models.Book.objects.all().aggregate(Max('price'))
    # res2 = models.Book.objects.all().aggregate(Min('price'))
    # res3 = models.Book.objects.all().aggregate(Sum('price'))
    # res4 = models.Book.objects.all().aggregate(Count('title'))
    # res5 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title'))
    # print(res5)

二、分组查询

 """
    分组查询
        
    关键字:annotate
    """
    # 1.统计每一本书的作者个数
    # res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num')
    # print(res)

    # 2.统计出每个出版社卖的最便宜的书的价格
    # res = models.Publish.objects.annotate(price_min=Min('book__price')).values('price_min')
    # print(res)

    # 3.统计不止一个作者的图书
    """
    1.统计每本书对应的作者个数
    2.基于上面的结果 筛选出作者个数大于1 的
    
    """
    # res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')
    # print(res)

    # 4.查询各个作者出的书的总价格
    # res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('sum_price')
    # print(res)

三、F、Q查询

F查询

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个我们自己设定的常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

 """
    F与Q查询
        我们之前在查询数据库的时候条件都是我们自己手写的
        但是现在出现了条件是从数据库里面获取的
    """
    # F
    from django.db.models import F,Q
    # 1.查询出卖出数大于库存数的书籍
    # res = models.Book.objects.filter(maichu__gt=F('kucun'))
    # print(res)

    # 2.将所有的书的价格 全部提高100块
    # models.Book.objects.update(price=F('price') + 100)

    # 3.了解  尝试着将所有的书的名字后面都加上 爆款

F可以帮我们取到表中某个字段对应的值来当作我的筛选条件,而不是我认为自定义常量的条件了,实现了动态比较的效果

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

基于此可以对表中的数值类型进行数学运算,如:将所有书的价格提高100元钱

Q查询

filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象

对条件包裹一层Q时候,filter即可支持交叉并的比较符(即‘与’ ‘或’ ‘非’ 等关系运算)

"""
    Q查询
    """
    # 1.查询书籍名称是python入门或者价格是544.44的书
    # res = models.Book.objects.filter(title='python入门',price=544.44)
    # res = models.Book.objects.filter(Q(title='python入门'),Q(price=544.44))  # 逗号就是and
    # res = models.Book.objects.filter(Q(title='python入门')|Q(kucun=666))  # 用来Q之后 就能够支持|表示或
    # res = models.Book.objects.filter(~Q(title='python入门')|Q(kucun=666))  # esc下面那个键 波浪号  表示非
    # print(res)

    # Q查询进阶用法   用Q产生对象 然后再使用
    # q = Q()
    # q.connector = 'or'
    # q.children.append(('title__icontains','p'))
    # # q.children.append(('kucun',666))
    # res = models.Book.objects.filter(q)
    # print(res)
    """
    字符串的左边 跟你的变量名条件书写一模一样
    """

我们可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。

同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

示例:

查询 库存数是100 并且 卖出数不是0 的产品

models.Product.objects.filter(Q(kucun=100)&~Q(maichu=0))

四、自定义char字段

# 自定义char类型字段
class MyCharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)'%self.max_length

运用自定义的char定义模型表的‘info’字段:

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)
    info = MyCharField(max_length=32,null=True)

    maichu = models.IntegerField(default=1000)
    kucun = models.IntegerField(default=1000)

    # 书籍与出版社 是一对多关系
    publish = models.ForeignKey(to='Publish')
    # 书籍与作者 是多对多
    authors = models.ManyToManyField(to='Author')
    """
    authors虚拟字段
        1.告诉orm自动帮你创建第三张关系表
        2.orm查询的时候  能够帮助你更加方便的查询
    """

五、查询优化(*****面试重点)

查询优化(面试比较喜欢问的)
        only与defer
        
        
        select_related和prefetch_related

代码示例:

 # 惰性查询
    # res = models.Book.objects.all()
    # res = models.Book.objects.values('title')
    # res = models.Book.objects.only('title')
    # for r in res:
    #     # print(r.title)
    #     print(r.price)
    """
    only会将括号内的字段对应的值 直接封装到返回给你的对象中  点该字段 不需要再走数据库
    一旦你点了不是括号内的字段  就会频繁的去走数据库查询
    """

    # res = models.Book.objects.defer('title')  # defer和only互为反关系
    # for r in res:
    #     print(r.title)
    """
    defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中  点该其他字段 不需要再走数据库
    一旦你点了括号内的字段  就会频繁的去走数据库查询
    """

    # res = models.Book.objects.select_related('publish')
    # res1 = models.Author.objects.select_related('author_detail')
    # # res = models.Book.objects.all()
    # for r in res1:
    #     print(r.author_detail)
    #     print(r.author_detail.phone)
    #     print(r.author_detail.addr)
    """
    select_related 会自动帮你做连表操作 然后将连表之后的数据全部查询出来封装给对象
    
    select_related括号内只能放外键字段
        并且多对多字段不能放
        
    如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
            select_related(外键字段__外键字段__外键字段...)

    """
    # prefetch_related
    res = models.Book.objects.prefetch_related('publish')
    # print(res)
    for r in res:
        print(r.publish.name)

    """
    prefetch_related  看似连表操作  其实是类似于子查询
    prefetch_related括号内只能放外键字段
        并且多对多字段不能放
        
    如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
            select_related(外键字段__外键字段__外键字段...)
    """

"""
第一个 内部自动连表 消耗的资源就在连表上   但是走数据库的次数较少

第二个 内部不做连表 消耗的资源就在查询次数上  但是给用户的感觉跟连表操作一样



"""

六、Django ORM中的事务操作

数据库中事务的4大特性,ACID:原子性、一致性、隔离性、持久性。

事务的提交:commit

事务的回滚:rollback

# django中如何开启事务
from django.db import transaction
with transaction.atomic():
    # 在该代码块中所写的orm语句 同属于一个事务

# 缩进出来之后自动结束

七、案例--图书管理系统

开启一个Django项目,需要注意事项:

1、首先在Navacat中建好数据库并在应用文件夹下的init.py文件中导入pymysql,在应用models.py 下建好模型表;

2、然后在settings.py文件下进行静态文件配置,在跟目录下创建static文件夹,放置bootstraip文件;

3、在templates文件夹中创建HTML文件时,注意配置{% load static%}  link   script   等配置代码;

4、POST提交请求时,注意要在settings.py文件中注释CRSF...中间件

代码如下:

app01文件夹:

import pymysql
pymysql.install_as_MySQLdb()
init.py
from django.db import models

# Create your models here.
"""
你在写orm语句的时候 跟你写sql语句一样
不要想着一次性写完
写一点查一点看一点
"""

# 自定义char类型字段
class MyCharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)'%self.max_length



class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)
    # info = MyCharField(max_length=32,null=True)
    #
    # maichu = models.IntegerField(default=1000)
    # kucun = models.IntegerField(default=1000)

    # 书籍与出版社 是一对多关系
    publish = models.ForeignKey(to='Publish')
    # 书籍与作者 是多对多
    authors = models.ManyToManyField(to='Author')
    """
    authors虚拟字段
        1.告诉orm自动帮你创建第三张关系表
        2.orm查询的时候  能够帮助你更加方便的查询
    """

    def __str__(self):
        return self.title


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

    def __str__(self):
        return self.name
    """return返回的数据必须是字符串类型"""



class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # author_detail = models.ForeignKey(unique=True,to='AuthorDetail')
    author_detail = models.OneToOneField(to='AuthorDetail')


    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=64)

    def __str__(self):
        return self.addr
models.py
from django.shortcuts import render,HttpResponse,redirect,reverse
from app01 import models
# Create your views here.

def home(request):
    return render(request,'home.html')


def book_list(request):
    # 将网站所有的书籍查询出来
    book_queryset = models.Book.objects.all()
    return render(request,'book_list.html',locals())


def add_book(request):
    if request.method == 'POST':
        title = request.POST.get('title')
        price = request.POST.get('price')
        publish_date = request.POST.get('publish_date')
        publish_id = request.POST.get('publish')
        authors_list = request.POST.getlist('authors')
        # 操作书籍表
        book_obj = models.Book.objects.create(title=title,price=price,publish_date=publish_date,publish_id=publish_id)
        # 操作书籍与作者的关系表
        book_obj.authors.add(*authors_list)
        # 跳转到展示页面
        _url = reverse('list')
        return redirect(_url)



    # 把出版社和作者全部查询出来
    publish_queryset = models.Publish.objects.all()
    authors_queryset = models.Author.objects.all()
    return render(request,'add_book.html',locals())


def edit_book(request,edit_id):
    # 获取到用户想要编辑的数据的主键值
    edit_obj = models.Book.objects.filter(pk=edit_id).first()
    if request.method == 'POST':
        title = request.POST.get('title')
        price = request.POST.get('price')
        publish_date = request.POST.get('publish_date')
        publish_id = request.POST.get('publish')
        authors_list = request.POST.getlist('authors')
        models.Book.objects.filter(pk=edit_id).update(title=title,price=price,publish_date=publish_date,publish_id=publish_id)
        edit_obj.authors.set(authors_list)
        # 跳转到书籍的展示页面
        _url = reverse('list')
        return redirect(_url)

    # 将用户想要编辑的数据对象 展示给用户看
    # 把出版社和作者全部查询出来
    publish_queryset = models.Publish.objects.all()
    authors_queryset = models.Author.objects.all()
    return render(request,'edit_book.html',locals())


def delete_book(request,delete_id):
    models.Book.objects.filter(pk=delete_id).delete()
    return redirect(reverse('list'))
views.py

BMS文件夹:

"""
Django settings for BMS project.

Generated by 'django-admin startproject' using Django 1.11.11.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ')9mson%8(483jjy+sof)83k$q%6!$r-9pwwjx+(dmestlf_-s4'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'BMS.urls'

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

WSGI_APPLICATION = 'BMS.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day61',
        'USER': 'root',
        'PASSWORD': "root",
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'CHARSET': 'utf8'
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')
]
settings.py
"""BMS URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 图书管理系统首页
    url(r'^$', views.home),
    # 图书展示页面
    url(r'^book_list/', views.book_list,name='list'),
    # 图书的添加页面
    url(r'^add_book/',views.add_book,name='add'),
    # 图书的编辑页面
    url(r'^edit_book/(\d+)/',views.edit_book,name='edit'),
    # 图书的删除页面
    url(r'^delete_book/(\d+)/',views.delete_book,name='delete')
]
urls.py

static文件夹:

存放bootstraip文件

templates文件夹:

{% extends 'home.html' %}


{% block content %}
<h2 class="text-center">添加页面</h2>
<form action="" method="post">
        <p>title:<input type="text" name="title" class="form-control"></p>
        <p>price:<input type="text" name="price"  class="form-control"></p>
        <p>publish_date:<input type="date" name="publish_date"  class="form-control"></p>
        <p>publish:
{#            将当前网站所有的出版社 展示给用户看#}
            <select name="publish" id="" class="form-control">
                {% for publish_obj in publish_queryset %}
                    <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                {% endfor %}
            </select>
        </p>
        <p>authors:
{#           将当前网站所有的作者 展示给用户看#}
            <select name="authors" id="" class="form-control" multiple>
                {% for author_obj in authors_queryset %}
                    <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
                {% endfor %}
            </select>
        </p>
        <input type="submit" class="btn btn-primary pull-right">
    </form>




{% endblock %}
add_book.html
{% extends 'home.html' %}


{% block content %}
<h2 class="text-center">图书列表</h2>
    <a href="{% url 'add' %}" class="btn btn-success">添加书籍</a>
    <table class="table table-bordered table-striped table-hover">
        <thead>
            <tr>
                <th>编号</th>
                <th>书名</th>
                <th>价格</th>
                <th>出版日期</th>
                <th>出版社</th>
                <th>作者</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for book_obj in book_queryset %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ book_obj.title }}</td>
                    <td>{{ book_obj.price }}</td>
                    <td>{{ book_obj.publish_date|date:'Y-m-d' }}</td>
                    <td>{{ book_obj.publish.name }}</td>
                    <td>
                        {% for author_obj in book_obj.authors.all %}
                            {% if forloop.last %}
                                {{ author_obj.name }}
                                {% else %}
                                {{ author_obj.name }},
                            {% endif %}
                        {% endfor %}

                    </td>
                    <td>
                        <a href="{% url 'edit' book_obj.pk %}" class="btn btn-primary btn-sm">编辑</a>
                        <a href="{% url 'delete' book_obj.pk %}" class="btn btn-danger btn-sm">删除</a>
                    </td>
                </tr>
            {% endfor %}


        </tbody>

    </table>
{% endblock %}
book_list.html
{% extends  'home.html' %}


{% block content %}
<h2 class="text-center">编辑页面</h2>
<form action="" method="post">
        <p>title:<input type="text" name="title" class="form-control" value="{{ edit_obj.title }}"></p>
        <p>price:<input type="text" name="price"  class="form-control" value="{{ edit_obj.price }}"></p>
        <p>publish_date:<input type="date" name="publish_date"  class="form-control" value="{{ edit_obj.publish_date|date:'Y-m-d' }}"></p>
        <p>publish:
{#            将当前网站所有的出版社 展示给用户看#}
            <select name="publish" id="" class="form-control">
                {% for publish_obj in publish_queryset %}
                    {% if edit_obj.publish == publish_obj %}
                        <option value="{{ publish_obj.pk }}" selected>{{ publish_obj.name }}</option>
                    {% else %}
                        <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                    {% endif %}
                {% endfor %}
            </select>
        </p>
        <p>authors:
{#           将当前网站所有的作者 展示给用户看#}
            <select name="authors" id="" class="form-control" multiple>
                {% for author_obj in authors_queryset %}
                    {% if author_obj in edit_obj.authors.all %}
                        <option value="{{ author_obj.pk }}" selected>{{ author_obj.name }}</option>
                    {% else %}
                        <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option>
                    {% endif %}
                {% endfor %}
            </select>
        </p>
        <input type="submit" class="btn btn-warning pull-right">
    </form>
{% endblock %}
edit_book.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
    <style>
        table {
            margin-top: 5px;
        }
    </style>

</head>
<body>
<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">图书管理系统</a>
    </div>
    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">书籍 <span class="sr-only">(current)</span></a></li>
        <li><a href="#">作者</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多 <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">搜索</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Welcome!</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多操作 <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li role="separator" class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-2">
            <div class="list-group">
              <a href="/" class="list-group-item active">
                首页
              </a>
              <a href="{% url 'list' %}" class="list-group-item">图书列表</a>
              <a href="#" class="list-group-item">出版社列表</a>
              <a href="#" class="list-group-item">作者列表</a>
              <a href="#" class="list-group-item">其他</a>
            </div>
        </div>
        <div class="col-md-10">
            <div class="panel panel-primary">
              <div class="panel-heading">
                <h3 class="panel-title">图书管理系统 <span class="glyphicon glyphicon-book pull-right"></span></h3>
              </div>
              <div class="panel-body">
                  {% block content %}
                  <div class="jumbotron">
                  <h1>欢迎来到最牛逼的图书管理系统</h1>
                  <p>亚洲最大的线上...</p>
                  <p><a class="btn btn-primary btn-lg" href="#" role="button">了解更多</a></p>
                </div>
                  {% endblock %}

              </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
home.html

猜你喜欢

转载自www.cnblogs.com/qinsungui921112/p/11741078.html