zoukankan      html  css  js  c++  java
  • Django开发:(3.1)ORM:单表操作

    MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动

    ORM是“对象-关系-映射”的简称。

    Mysql中的表对应python中的类,表的字段对应类的属性,表的记录对应类的实例化的对象

    单表操作

    创建表

    1. 创建模型

     

    创建名为app01的app,在app01下的models.py中创建模型:

    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):  # 类名可以随便起,但一定得继承 models.Model
        id = models.AutoField(primary_key=True)  # AutoField表示自增字段; primary_key=True 表示是主键
        title = models.CharField(max_length=32)
        # state = models.BooleanField()
        pub_date = models.DateField()
        price = models.DecimalField(max_digits=8,decimal_places=2)
        publish = models.CharField(max_length=32)

    2. 更多字段和参数

    每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。

    3. settings配置

    若想将模型转为mysql数据库中的表,需要在settings中配置:

    DATABASES = {
        'default':{
            'ENGINE':'django.db.backends.mysql',
            'NAME':'orm', # 要连接的数据库,连接前需要先创建好
            'USER':'root',  # 连接数据库的用户名
            'PASSWORD':'tj037778',  # 连接数据库的密码
            'HOST':'127.0.0.1',  # 连接主机
            'PORT':3306  # 端口
        }
    }

    注意1:NAME即数据库的名字,在mysql连接前该数据库必须已经创建(ORM只能处理到表这一层,数据库操作不了),而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名(project)文件下的__init__(ORM/ORM/__init__.py),在里面写入:

    import pymysql
    
    pymysql.install_as_MySQLdb()

    最后通过两条数据库迁移命令即可在指定的数据库中创建表 :

    python manage.py makemigrations
    python manage.py migrate
    # makemigrations 后并没有在数据库生成表,而是在对应的 migrationsns 文件夹下生成了 py 文件
    # migrate 时会执行 migrations文件夹下的 py文件(至于执行哪个py文件,程序会先去 django自带的 django_migrations 这张表中去查,如果migrationsns 文件夹下人某个py文件在 django_migrations 这张表已经存在,则 migrate时则会跳过这个py文件不执行,即已经执行过的py文件会存放在 django_migrations表中)
    # 修改数据库的时候,尽量用 makemigrations 和 migrate,不要直接在Navicat 中修改

    注意2:确保配置文件中的INSTALLED_APPS中写入我们创建的app名称

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

    注意3:如果报错如下:

    django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

    MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:

    通过查找路径:D:pythonLibsite-packagesdjangodbackendsmysqlase.py

    把里面的

    if version < (1, 3, 3):
        raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

    注释掉 就OK了。

    注意4: 如果想打印orm转换过程中的sql,需要在settings中进行如下配置:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }

    添加表记录

    urls.py

    from django.contrib import admin
    from django.urls import path
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path(r'index/',views.index)
    ]

    app01/models.py

    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):  # 类名可以随便起,但一定得继承 models.Model
        id = models.AutoField(primary_key=True)  # AutoField表示自增字段; primary_key=True 表示是主键
        title = models.CharField(max_length=32)
        # state = models.BooleanField()
        pub_date = models.DateField()
        price = models.DecimalField(max_digits=8,decimal_places=2)
        publish = models.CharField(max_length=32)

    app01/views.py

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    # 先把模型导入进来
    from app01.models import Book
    
    def index(request):
        # 添加表记录
    
        # 方式一:实例化Book对象
        book_obj = Book(id=1,title="python全栈开发",pub_date="2018-6-7",price=100,publish="IT出版社")   # pub_date是一个日期类型,一定得按照"年-月-日"的格式
        book_obj.save()  # save()之后记录才会生成 # 表里面的一条记录就是类的一个对象
    
        # 方式二:用 objects去调用create; create方法有返回值,返回值就是生成的记录对象
        book_obj2 = Book.objects.create(title="linux运维",pub_date="2015-6-7",price=100,publish="IT出版社")  # id是自增的,所以无需再写
        # 这种方式不需要 save();.objects.create(kwargs) 直接就在数据库中生成了一条记录(对象),并把这个对象返回给 book_obj2(我们也就可以打印book_obj2中的属性)
        print(book_obj2.pub_date)
    
    
        return HttpResponse("ok")

    单表查询:

    models.py

    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):  # 类名可以随便起,但一定得继承 models.Model
        id = models.AutoField(primary_key=True)  # AutoField表示自增字段; primary_key=True 表示是主键
        title = models.CharField(max_length=32)
        # state = models.BooleanField()
        pub_date = models.DateField()
        price = models.DecimalField(max_digits=8,decimal_places=2)
        publish = models.CharField(max_length=32)
    
        def __str__(self):  # 只是控制了对象的打印形式
            return self.title

    views.py

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    # 先把模型导入进来
    from app01.models import Book
    
    def index(request):
    
        # #######################查询表结构API#######################
        # 注意:要知道每个方法的返回值是什么、以及每个方法是谁来调用的
    
        # 1. all() :查询所有结果;返回值是一个QuerySet数据类型(Django自定义的数据类型),调用者是 objects
        all_books = Book.objects.all()
        print(all_books)
        # Book类没有 __str()__方法时的打印结果:
        # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>]>
        # Book有 __str()__ 方法时的打印结果:
        # <QuerySet [<Book: python全栈开发>, <Book: linux运维>]>
        # QuerySet数据类型:相当于 [obj1,obj2,...],可用列表的方式去处理它
    
        for obj in all_books:  # 支持遍历
            print(obj.title,obj.pub_date)
    
        print(all_books[1].publish)  # 支持索引
    
        # 2. first(),last()方法;返回值是一个model(模型)对象,调用者是 QuerySet对象
        book1 = Book.objects.all().first()  # 相当于 Book.objects.all()[0]
        book2 = Book.objects.all().last()
    
        print(book1,book2)
    
        # 3. filter()方法:返回值:QuerySet对象,调用者:管理器(objects)
        books = Book.objects.filter(title="python全栈开发",price=100)  # filter()的作用相当于sql语句的where;# 返回值:[obj1,obj2,....];多个过滤条件用逗号分隔
        print(books)
        # filter()方法也可以调用 first(),last()方法
        print(books.first())
    
        # 4. get()方法:有且只有一个查询结果时才有意义;如果有多个查询结果或者没有查询结果,报错;所以,返回值:model对象
        book_get = Book.objects.get(title="python全栈开发")
        print(book_get.price)
    
        # 5. exclude():排除条件的过滤,对应filter();返回QuerySet
        ret = Book.objects.exclude(title="python全栈开发")
        print(ret)
    
        # 6. order_by():按照某种条件排序(默认是按照id);返回值:QuerySet,调用者:QuerySet
        book_order_asc = Book.objects.all().order_by("id")
        print(book_order_asc)
        book_order_desc = Book.objects.all().order_by("-id")  # 按照降序排列
        print(book_order_desc)
        book_price_desc = Book.objects.all().order_by("-price")  # 按照价格降序排列
        print(book_price_desc)
        # Book.objects.all().order_by("-price","id") # 先按照价格降序排列,再按照id升序
        # 要熟悉orm的链式操作
    
        # 7. reverse() :对查询结果反向排序
    
        # 8. count():计数;返回值:int,调用者:QuerySet
        Book.objects.all().count()  # 计数里面有多少个元素
    
        # 9. exists():如果QuerySet包含数据,就返回True,否则返回False
        ret_exists = Book.objects.all().exists()  # 判断 Book.objects.all() 里面是否有数据
    
        # 10. values(*field):field代表字段;values()具有遍历作用,返回一个QuerySet --- 一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列;返回值:QuerySet(列表里面放字典),调用者:QuerySet
        # values()方法很重要
        ret_values = Book.objects.all().values("price","title")
        print(ret_values)
        # <QuerySet [{'price': Decimal('100.00'), 'title': 'python全栈开发'}, {'price': Decimal('100.00'), 'title': 'linux运维'}]>
        print(ret_values[0].get("price"))
        # 100.00
    
        # 11. values_list(*field):它与values()非常相似,它返回的QuerySet里面是一个元组序列,values返回的是一个字典序列
        ret_values_list = Book.objects.all().values_list("price", "title")
        print(ret_values_list)
        # <QuerySet [(Decimal('100.00'), 'python全栈开发'), (Decimal('100.00'), 'linux运维')]>
    
        # 12. distinct():从返回结果中剔除重复纪录(通常配合values,values_list一起使用)
        ret_distinct = Book.objects.all().values("price").distinct()
        print(ret_distinct)
        # <QuerySet [{'price': Decimal('100.00')}]>
        # 注: Book.objects.all().distinct() 这种写法没有任何意义
    
        # #######################查询表结构之模糊查询(都是双下划线)#######################
        # 1. __gt :大于;__lt:小于;返回值:QuerySet
        price__gt = Book.objects.filter(price__gt=50,price__lt=200)
        print("__gt",price__gt)
    
        # 2. __startswith:以什么开头;返回值:QuerySet
        obj_start = Book.objects.filter(title__startswith="py")
        print(obj_start)
    
        # 3. __contains:包含什么;返回值:QuerySet
        # 4. __icontains:包含某些元素(不区分大小写)
        obj_contains = Book.objects.filter(title__contains="x")
        print(obj_contains)
    
        # 5. __in = [] :是列表中的一个;返回值:QuerySet
        obj_in = Book.objects.filter(price__in=[100,150,200])
        print(obj_in)
    
        # 6. __year : 某一年的(只有date类型有);返回值:QuerySet
        obj_year = Book.objects.filter(pub_date__year=2018)
        print(obj_year)
    
        # 7. __range = [] : 在某个区间(包含两端)
        obj_range = Book.objects.filter(price__range=[50,100])
        print("range",obj_range)
    
        return HttpResponse("ok")

    补充:例如上面的4.get() 方法,如果值不存在,可以捕获到这个异常

    from django.core.exceptions import ObjectDoesNotExist  # ObjectDoesNotExist 值不存在的异常类型

    单表之删除和编辑

    views.py

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    # 先把模型导入进来
    from app01.models import Book
    
    def index(request):
        # #######################删除、修改表记录#######################
        # delete() : 删除;调用者:QuerySet对象 或者 model对象;返回值是删除元素的一些信息
        # Book.objects.filter(pub_date__year=2018).delete()  # 需要都把记录查询出来才能删除;调用者:QuerySet对象
        # Book.objects.filter(pub_date__year=2015).first().delete()  # 调用者:model对象
    
        # update():编辑记录; 调用者:QuerySet;返回值:更新的条数
        Book.objects.filter(title__contains="linux").update(title="linux运营维护")
    
    
        return HttpResponse("ok")

    图书管理系统

    settings.py

    """
    Django settings for bookms project.
    
    Generated by 'django-admin startproject' using Django 2.0.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/2.0/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/2.0/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/2.0/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'm6=&s25aszxks#m(5f57mdpi)hc%v7#&e0$kmak48@80xr7t0h'
    
    # 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 = 'bookms.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 = 'bookms.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
    
    # DATABASES = {
    #     'default': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    #     }
    # }
    DATABASES = {
        'default':{
            'ENGINE':'django.db.backends.mysql',
            'NAME':'bookms', # 要连接的数据库,连接前需要先创建好
            'USER':'root',  # 连接数据库的用户名
            'PASSWORD':'tj037778',  # 连接数据库的密码
            'HOST':'127.0.0.1',  # 连接主机
            'PORT':3306  # 端口
        }
    }
    
    # Password validation
    # https://docs.djangoproject.com/en/2.0/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/2.0/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/2.0/howto/static-files/
    
    STATIC_URL = '/static/'  # 若存放静态文件的static目录在app目录下,则该句生效,无需定义下面的
    # STATICFILES_DIRS = [
    #     os.path.join(BASE_DIR,"static"),
    # ]    # 若存放静态文件的static目录在project目录下,则用该定义
    
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }

    urls.py

    """bookms URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.0/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path,re_path
    
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path(r"addbook/",views.addbook),
        path(r"books/",views.books),
    
        # (d+)用于匹配获取表记录的主键(书的id)
        re_path(r"books/(d+)/delete",views.bookdel),
        re_path(r"books/(d+)/edit",views.bookedit)
    ]

    views.py

    from django.shortcuts import render,HttpResponse,redirect
    
    # Create your views here.
    
    # 把模型表引入
    from app01.models import Book
    
    def addbook(request):
        # 由于templates/addbook.html 中 form标签的 action没写,所以还是提交到了当前页面index.html
        if request.method == "POST":
            title = request.POST.get("title")
            price = request.POST.get("price")
            date = request.POST.get("date")
            press = request.POST.get("press")
    
            # 添加记录
            book_obj = Book.objects.create(title=title,price=price,pub_date=date,publish=press)
    
            return redirect("/books/")
    
        return render(request,"addbook.html")
    
    def books(request):
        books_list = Book.objects.all()
    
        return render(request,"books.html",locals())
    
    def bookdel(request,pk):
        # 把对应ID的书删除
        Book.objects.filter(id=pk).delete()
    
        # redirect()的作用就是让浏览器往重定向的路径再发一次请求
        return redirect("/books/")
    
    def bookedit(request,id):
        # 编辑对应ID的书
    
        # 先获取对应书对象
        book_obj = Book.objects.filter(id=id).first()
    
        # 由于编辑后的内容还是提交到当前页面,所以在这个函数里面要判断请求是否就POST
        if request.method == "POST":
            # 获取编辑后的内容
            title = request.POST.get("title")
            price = request.POST.get("price")
            date = request.POST.get("date")
            press = request.POST.get("press")
    
            # 把编辑后的内容更新到表中
            Book.objects.filter(id=id).update(title=title,price=price,pub_date=date,publish=press)
            # 更新完后重定向到 books.html 页面
            return redirect("/books/")
    
        return render(request,"editbook.html",{"book_obj":book_obj})

    models.py

    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        pub_date = models.DateField()
        price = models.DecimalField(max_digits=8, decimal_places=2)
        publish = models.CharField(max_length=32)

    books.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>addbook</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    
        <style>
            .container{
                margin-top: 70px;
            }
            .btn{
                margin-bottom: 10px;
            }
        </style>
    
    </head>
    <body>
    <h3>查看书籍</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <a href="/addbook/" class="btn btn-primary">添加书籍</a>
                {# .table-striped 类可以给 <tbody> 之内的每一行增加斑马条纹样式;.table-bordered 类为表格和其中的每个单元格增加边框。#}
                <table class="table table-striped table-bordered">
                    <thead>
                        <tr>
                            <th>书籍名称</th>
                            <th>价格</th>
                            <th>出版日期</th>
                            <th>出版社</th>
                            <th>编辑</th>
                            <th>删除</th>
                        </tr>
                    </thead>
                    <tbody>
                        {# 遍历 books_list是的每一个对象(表记录),把每条表记录添加到 table的一行中 #}
                        {% for book in books_list %}
                            <tr>
                                <td>{{ book.title }}</td>
                                <td>{{ book.price }}</td>
                                {# 利用date过滤器格式化时间样式 #}
                                <td>{{ book.pub_date|date:"Y-m-d" }}</td>
                                <td>{{ book.publish }}</td>
                                {# 动态的为每个a标签添加索引 #}
                                <td><a href="/books/{{ book.pk }}/edit" class="btn btn-info">编辑</a></td>
                                {# 把主键id添加到a标签的路径中;.pk表示model对象的主键 #}
                                <td><a href="/books/{{ book.pk }}/delete" class="btn btn-danger">删除</a></td>
                            </tr>
    
                        {% endfor %}
    
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    
    </body>
    </html>

    addbook.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>addbook</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    
        <style>
            .container{
                margin-top: 70px;
            }
            .btn{
                margin-top: 10px;
            }
        </style>
    
    </head>
    <body>
    <h3>添加书籍</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form action="" method="post">
                    {% csrf_token %}
                    <div>
                        <label for="">书籍名称</label>
                        {# form-controlform-control控件,可以为input元素添加CSS定制样式#}
                        <input type="text" class="form-control" name="title">
                    </div>
                    <div>
                        <label for="">价格</label>
                        <input type="text" class="form-control" name="price">
                    </div>
                    <div>
                        <label for="">出版日期</label>
                        {# date类型:能够下拉选择日期 #}
                        <input type="date" class="form-control" name="date">
                    </div>
                    <div>
                        <label for="">出版社</label>
                        <input type="text" class="form-control" name="press">
                    </div>
                    {# btn btn-success:绿色按钮;pull-right:右移 #}
                    <input type="submit" class="btn btn-success pull-right">
                </form>
            </div>
        </div>
    </div>
    
    </body>
    </html>

    editbook.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>addbook</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    
        <style>
            .container{
                margin-top: 70px;
            }
            .btn{
                margin-top: 10px;
            }
        </style>
    
    </head>
    <body>
    <h3>编辑书籍</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                {# form标签的action没写,所以默认还是会提交到当前页面 #}
                <form action="" method="post">
                    {% csrf_token %}
                    <div>
                        <label for="">书籍名称</label>
                        {# 编辑时书名这一栏的内容是该对象原先的title;其它栏同理 #}
                        <input type="text" class="form-control" name="title" value="{{ book_obj.title }}">
                    </div>
                    <div>
                        <label for="">价格</label>
                        <input type="text" class="form-control" name="price" value="{{ book_obj.price }}">
                    </div>
                    <div>
                        <label for="">出版日期</label>
                        {# 此处的日期也需要用date过滤器格式化,要不然显示不出来 #}
                        <input type="date" class="form-control" name="date" value="{{ book_obj.pub_date|date:'Y-m-d' }}">
                    </div>
                    <div>
                        <label for="">出版社</label>
                        <input type="text" class="form-control" name="press" value="{{ book_obj.publish }}">
                    </div>
                    {# btn btn-success:绿色按钮;pull-right:右移 #}
                    <input type="submit" class="btn btn-success pull-right">
                </form>
            </div>
        </div>
    </div>
    
    </body>
    </html>
  • 相关阅读:
    cocos2dx学习资源汇总(转)
    Cocos2dx 绘制动画
    Cocosdx中CCMenuItem菜单项进一步介绍
    Cocos2dx中场景切换
    ActionScript3.0 大数据类型
    Cocos2dx 菜单项
    as3.0 Function.apply()与Function.call()方法简介
    Inherited用法代码示例
    区分保留字跟关键字
    标题栏上画按钮代码示例
  • 原文地址:https://www.cnblogs.com/neozheng/p/9151510.html
Copyright © 2011-2022 走看看