zoukankan      html  css  js  c++  java
  • 055.Python前端Django模型ORM


    由于前面在centos实验的过程中,pymql一直有属性错误,很难排查出问题,重新做了一个ubuntu的桌面系统同时使用pycharm开发工具作为学习开发工具,具体原因是因为在项目命名出现问题,和自己带的模块冲突,导致不能成功

    一 ORM简介

    对象关系映射(Object Relational Mapping,简称ORM)。

    简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

    通过一张图来介绍一下数据库与python代码之间的一个关系:

    1.1 ORM特点

    ORM的优点

    • 不用写繁琐的SQL语句,用咱们熟悉的python代码,就能实现对数据的操作,提高开发效率;
    • 可以平滑的操作,切换数据库。

    ORM的缺点

    • ORM代码转换为SQL语句时,需要花费一定的时间,执行效率会有所降低;
    • 长期写ORM代码,导致写SQL语句能力,会有所减弱。 

    1.2 改进

    如果想打印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',
            },
        }
    }  
    settings配置
    复制代码

    二 单表操作

    django使用MySQL的流程:

    2.1 创建MySQL数据库

    注意:ORM无法操作到数据库级别,只能操作到数据表。

    安装mysql

    apt-get install mysql-server mysql-common mysql-client

    root@darren-virtual-machine:~# systemctl status mysql

    复制代码
    mysql.service - MySQL Community Server
       Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
       Active: active (running) since Sun 2020-04-05 11:46:45 CST; 58s ago
     Main PID: 16219 (mysqld)
        Tasks: 27 (limit: 11869)
       CGroup: /system.slice/mysql.service
               └─16219 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
    
    4月 05 11:46:44 darren-virtual-machine systemd[1]: Starting MySQL Community Server...
    4月 05 11:46:45 darren-virtual-machine systemd[1]: Started MySQL Community Server.
    复制代码

    root@darren-virtual-machine:~# mysql -V

    mysql  Ver 14.14 Distrib 5.7.29, for Linux (x86_64) using  EditLine wrapper

    root@darren-virtual-machine:~# cat /etc/mysql/debian.cnf

    复制代码
    # Automatically generated for Debian scripts. DO NOT TOUCH!
    [client]
    host     = localhost
    user     = debian-sys-maint
    password = gpitUmpta6ImT8hh
    socket   = /var/run/mysqld/mysqld.sock
    [mysql_upgrade]
    host     = localhost
    user     = debian-sys-maint
    password = gpitUmpta6ImT8hh
    socket   = /var/run/mysqld/mysqld.sock
    复制代码

    可以使用上面的用户名和密码,也可以直接登录

    登录mysql

    2.2  修改密码

    复制代码
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    
    mysql> use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> update user set authentication_string=PASSWORD("123456")  where user='root';
    Query OK, 1 row affected, 1 warning (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 1
    
    mysql> update user set plugin="mysql_native_password";
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 4  Changed: 1  Warnings: 0
    
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> quit
    复制代码

    2.3  登进数据库建库操作

    root@darren-virtual-machine:~# mysql -uroot -p123456

    复制代码
    mysql> create database django default charset=utf8;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | django             |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    复制代码

    三  创建项目连接数据库

    3.1 创建一个新的项目

    root@darren-virtual-machine:~# cd /root/PycharmProjects/

    root@darren-virtual-machine:~/PycharmProjects# django-admin startproject mystie

    root@darren-virtual-machine:~/PycharmProjects# cd mysite/

    root@darren-virtual-machine:~/PycharmProjects/mysite# tree ./*

    复制代码
    ./manage.py [error opening dir]
    ./mysite
    ├── asgi.py
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
    复制代码

    3.2 创建一个app应用

    root@darren-virtual-machine:~/PycharmProjects/mysite# python3 manage.py startapp app01

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim mysite/settings.py

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

    3.3  在settings.py里设置数据库连接

    复制代码
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'django',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': "root",
            'PASSWORD': "123456",
        }
    }
    复制代码

    3.4 pymysql操作

    root@darren-virtual-machine:~/PycharmProjects/mysite#  pip3 install pymysql

    Collecting pymysql
      Downloading PyMySQL-0.9.3-py2.py3-none-any.whl (47 kB)
         |████████████████████████████████| 47 kB 175 kB/s
    Installing collected packages: pymysql
    Successfully installed pymysql-0.9.3

    3.4.1  告诉Django使用pymysql模块连接mysql数据库

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim mysite/__init__.py 

    # 在与settings.py同级目录下的__init__.py中
    import pymysql
    pymysql.install_as_MySQLdb()

    3.4.2 创建模型(在models.py中写类)

    [root@node10 pymysql]# cat app01/models.py

    复制代码
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
            title = models.CharField(max_length=32)
            author = models.CharField(max_length=32)
            publisher = models.CharField(max_length=32)
            price = models.DecimalField(max_digits=5, decimal_places=2)
            pub_date = models.DateField()
    复制代码

    扩展:更多字段和参数

    每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

    更多字段:

     更多字段

    更多参数:

     更多参数

    3.4.3 执行数据量迁移的命令

    root@darren-virtual-machine:~/PycharmProjects/mysite#  python3 manage.py  makemigrations

    报错如下

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

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim /usr/local/lib/python3.6/dist-packages/django/db/backends/mysql/base.py

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

    注释掉 就OK了。

    继续执行

    root@darren-virtual-machine:~/PycharmProjects/mysite#  python3 manage.py  makemigrations

    Migrations for 'app01':
      app01/migrations/0001_initial.py
        - Create model Book

    root@darren-virtual-machine:~/PycharmProjects/mysite# ll app01/migrations/

    -rw-r--r-- 1 root root  739 4月   5 16:40 0001_initial.py
    -rw-r--r-- 1 root root    0 4月   5 14:11 __init__.py
    drwxr-xr-x 2 root root 4096 4月   5 16:40 __pycache__/

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/migrations/0001_initial.py

    复制代码
    # Generated by Django 3.0.5 on 2020-04-05 08:40
    
    from django.db import migrations, models
    
    
    class Migration(migrations.Migration):
    
        initial = True
    
        dependencies = [
        ]
    
        operations = [
            migrations.CreateModel(
                name='Book',
                fields=[
                    ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                    ('title', models.CharField(max_length=32)),
                    ('author', models.CharField(max_length=32)),
                    ('publisher', models.CharField(max_length=32)),
                    ('price', models.DecimalField(decimal_places=2, max_digits=5)),
                    ('pub_date', models.DateField()),
                ],
            ),
        ]
    复制代码

     3.4.4 迁移操作

    root@darren-virtual-machine:~/PycharmProjects/mysite# python3 manage.py  migrate

    复制代码
    Operations to perform:
      Apply all migrations: admin, app01, auth, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying app01.0001_initial... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying sessions.0001_initial... OK
    复制代码

    查看数据库

    复制代码
    mysql> show tables;
    +----------------------------+
    | Tables_in_django           |
    +----------------------------+
    | app01_book                 |
    | auth_group                 |
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+
    11 rows in set (0.00 sec)
    
    mysql> desc app01_book;
    +-----------+--------------+------+-----+---------+----------------+
    | Field     | Type         | Null | Key | Default | Extra          |
    +-----------+--------------+------+-----+---------+----------------+
    | id        | int(11)      | NO   | PRI | NULL    | auto_increment |
    | title     | varchar(32)  | NO   |     | NULL    |                |
    | author    | varchar(32)  | NO   |     | NULL    |                |
    | publisher | varchar(32)  | NO   |     | NULL    |                |
    | price     | decimal(5,2) | NO   |     | NULL    |                |
    | pub_date  | date         | NO   |     | NULL    |                |
    +-----------+--------------+------+-----+---------+----------------+
    复制代码

    四  对数据库的操作 

    4.1 添加表记录

    配置url

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim mysite/urls.py 

    复制代码
    from django.contrib import admin
    from django.urls import path,include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('app01/', include("app01.urls")),
    ]
    复制代码

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim app01/urls.py

    from django.urls import path,re_path
    from app01 import views
    urlpatterns = [
        path('add_book/', views.add_book),
    ]

    视图文件

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim app01/views.py 

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:通过类实例化对象的方式。注意:一定要对象.save()
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            book_obj.save()
        return HttpResponse("新增成功")
    复制代码

    html模板文件

    创建templates目录

    root@darren-virtual-machine:~/PycharmProjects/mysite# mkdir templates

    注册template

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim mysite/settings.py

    复制代码
    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',
                ],
            },
        },
    ]
    复制代码

    root@darren-virtual-machine:~/PycharmProjects/mysite# vim templates/add_book.html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>新增书籍</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>书名:<input type="text" name="title"></p>
        <p>作者:<input type="text" name="author"></p>
        <p>出版社:<input type="text" name="publisher"></p>
        <p>价格:<input type="text" name="price"></p>
        <p>出版时间:<input type="text" name="pub_date"></p>
        <input type="submit">
    </form>
    
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/app01/add_book

     提交

     

    查看数据库

    mysql> select * from app01_book;

    复制代码
    +----+-----------+-----------+-----------------+--------+------------+
    | id | title     | author    | publisher       | price  | pub_date   |
    +----+-----------+-----------+-----------------+--------+------------+
    |  1 | 红楼梦     | 曹雪芹     | 清华出版社       | 165.00  | 2018-12-12 |
    +----+-----------+-----------+-----------------+--------+------------+
    1 row in set (0.00 sec)
    复制代码

    方式二:通过ORM提供的objects提供的方法 create来实现。

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py 

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
    复制代码

    访问插入数据http://127.0.0.1:8000/app01/add_book

    数据库查看记录

    mysql> select * from app01_book;

    复制代码
    +----+--------------+-----------+-----------------+--------+------------+
    | id | title        | author    | publisher       | price  | pub_date   |
    +----+--------------+-----------+-----------------+--------+------------+
    |  1 | 红楼梦        | 曹雪芹     | 清华出版社        | 165.00 | 2018-12-12 |
    |  2 | 三国演义      | 罗贯中     | 北大出版社        | 199.00 | 2018-12-23 |
    +----+--------------+-----------+-----------------+--------+------------+
    复制代码

    4.2 查询操作

    4.2.1 查询API

    复制代码
    <1> all():                  查询所有结果     
    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
    <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,                            如果符合筛选条件的对象超过一个或者没有都会抛出错误。 
    <4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象 
    <5> order_by(*field):       对查询结果排序
    <6> reverse():              对查询结果反向排序 
    <7> count():                返回数据库中匹配查询(QuerySet)的对象数量。  
    <8> first():                返回第一条记录  
    <9> last():                返回最后一条记录  
    <10> exists():              如果QuerySet包含数据,就返回True,否则返回False 
    <11> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列                            model的实例化对象,而是一个可迭代的字典序列
    <12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 
    <13> distinct():            从返回结果中剔除重复纪录
    复制代码

    4.2.2 基于双下划线的模糊查询

    复制代码
    Book.objects.filter(price__in=[100,200,300])
    Book.objects.filter(price__gt=100)
    Book.objects.filter(price__lt=100)
    Book.objects.filter(price__range=[100,200])
    Book.objects.filter(title__contains="法")
    Book.objects.filter(title__icontains="python")  # 不区分大小写
    Book.objects.filter(title__startswith="九")
    Book.objects.filter(pub_date__year=2018)
    复制代码

    4.2.3 实例

    添加测试数据

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            #book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #添加数据,添加完成后,及时删除
            models.Book.objects.create(title="水浒传",author="施耐庵",price=180, publisher="北电出版社", pub_date="2019-1-12")
            models.Book.objects.create(title="西游记",author="吴承恩",price=185, publisher="北大出版社", pub_date="2019-2-12")
            models.Book.objects.create(title="独孤九剑", author="风清扬",price = 190, publisher = "华山出版社", pub_date = "2019-1-15")
            models.Book.objects.create(title="葵花宝典", author="东方不败", price=120, publisher="黑木崖出版社", pub_date="2019-1-20")
            models.Book.objects.create(title="易筋经", author="方丈大师", price=140, publisher="少林出版社", pub_date="2019-1-23")
            models.Book.objects.create(title="道德经", author="老子", price=176, publisher="北大出版社", pub_date="2019-2-23")
            models.Book.objects.create(title="论语", author="孔子弟子", price=165, publisher="北电出版社", pub_date="2019-2-13")
            models.Book.objects.create(title="九阳神功", author="张无忌", price=130, publisher="少林出版社", pub_date="2018-1-23")
            models.Book.objects.create(title="九阴真经", author="黄裳", price=145, publisher="大宋出版社", pub_date="2017-3-23")
        return HttpResponse("新增成功")
    复制代码

    访问http://127.0.0.1:8000/app01/add_book,点击submit

    查看数据库

    mysql> select * from app01_book;

    复制代码
    mysql> select * from app01_book;
    +----+--------------+--------------+--------------------+--------+------------+
    | id | title        | author       | publisher          | price  | pub_date   |
    +----+--------------+--------------+--------------------+--------+------------+
    |  1 | 红楼梦       | 曹雪芹       | 清华出版社         | 165.00 | 2018-12-12 |
    |  2 | 三国演义     | 罗贯中       | 北大出版社         | 199.00 | 2018-12-23 |
    |  3 | 水浒传       | 施耐庵       | 北电出版社         | 180.00 | 2019-01-12 |
    |  4 | 西游记       | 吴承恩       | 北大出版社         | 185.00 | 2019-02-12 |
    |  5 | 独孤九剑     | 风清扬       | 华山出版社         | 190.00 | 2019-01-15 |
    |  6 | 葵花宝典     | 东方不败     | 黑木崖出版社       | 120.00 | 2019-01-20 |
    |  7 | 易筋经       | 方丈大师     | 少林出版社         | 140.00 | 2019-01-23 |
    |  8 | 道德经       | 老子         | 北大出版社         | 176.00 | 2019-02-23 |
    |  9 | 论语         | 孔子弟子     | 北电出版社         | 165.00 | 2019-02-13 |
    | 10 | 九阳神功     | 张无忌       | 少林出版社         | 130.00 | 2018-01-23 |
    | 11 | 九阴真经     | 黄裳         | 大宋出版社         | 145.00 | 2017-03-23 |
    +----+--------------+--------------+--------------------+--------+------------+
    复制代码

    必须恢复views.py,否则会重复添加

    编辑路由

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/urls.py

    复制代码
    from django.urls import path,re_path
    from app01 import views
    urlpatterns = [
        path('add_book/', views.add_book),
        path('query_book',views.query_book),
    ]
    复制代码

    定义视图函数

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
        return HttpResponse("新增成功")
    def query_book(request):
        #all,获取所有结果
        books = models.Book.objects.all()
        print(books)
    
        return HttpResponse("查询成功")
    复制代码

    访问http://127.0.0.1:8000/app01/query_book

    输出结果

    [05/Apr/2020 11:59:21] "GET /app01/add_book/ HTTP/1.1" 200 618
    <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (4)>, <Book: Book object (5)>, <Book: Book object (6)>, <Book: Book object (7)>, <Book: Book object (8)>, <Book: Book object (9)>, <Book: Book object (10)>, <Book: Book object (11)>]>
    [05/Apr/2020 11:59:26] "GET /app01/query_book HTTP/1.1" 200 12

    model返回一个title值

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/models.py

    复制代码
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
            title = models.CharField(max_length=32)
            author = models.CharField(max_length=32)
            publisher = models.CharField(max_length=32)
            price = models.DecimalField(max_digits=5, decimal_places=2)
            pub_date = models.DateField()
            def __str__(self):
                    return self.title
    复制代码

    再次访问查看

    [05/Apr/2020 12:04:48] "GET /app01/query_book HTTP/1.1" 200 12
    <QuerySet [<Book: 红楼梦>, <Book: 三国演义>, <Book: 水浒传>, <Book: 西游记>, <Book: 独孤九剑>, <Book: 葵花宝典>, <Book: 易筋经>, <Book: 道德经>, <Book: 论语>, <Book: 九阳神功>, <Book: 九阴真经>]>

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
        return HttpResponse("新增成功")
    def query_book(request):
        #filter Query 对象,类似于列表,获取满足条件的对象,filter可以满足多个条件,之间关系为and
        books_filter = models.Book.objects.filter(pk=3)
        print(books_filter)
        #get,获取对象,没有结果或者有多个结果 会报错
        books_get = models.Book.objects.get(pk=3)
        print(books_get,type(books_get))
        #exclude,query类型,和filter相反,排除满足条件的类型
        books_exclude = models.Book.objects.exclude(pk=3)
        print(books_exclude)
        #order_by默认升序,降序前面添加-即可
        books_order_by = models.Book.objects.order_by("price")
        print(books_order_by)
        books_order_by = models.Book.objects.order_by("-price")
        print(books_order_by)
        #reverse
        books_reverse = models.Book.objects.order_by("-price").reverse()
        print(books_reverse)
        #first获取第一条
        book_first= models.Book.objects.filter(pk=4).first()
        print(book_first)
        #exist判断结果是否讯在,存在返回true
        books_exist = models.Book.objects.exclude(pk=4)
        print(books_exist,type(books_exist))
        #vaules,QUeryset类型,类似于字典
        books_vaules = models.Book.objects.values("title","price")
        print(books_vaules,type(books_vaules))
        # vaules_list,QUeryset类型,类似于元祖
        books_vaules1 = models.Book.objects.values_list("title","price")
        print(books_vaules1,type(books_vaules1))
        #distinct,去除重复
        books = models.Book.objects.values("publisher").distinct()
        print(books,type(books))
    
        return HttpResponse("查询成功")
    复制代码

    查询结果

    复制代码
    <QuerySet [<Book: 水浒传>]>
    水浒传 <class 'app01.models.Book'>
    <QuerySet [<Book: 红楼梦>, <Book: 三国演义>, <Book: 西游记>, <Book: 独孤九剑>, <Book: 葵花宝典>, <Book: 易筋经>, <Book: 道德经>, <Book: 论语>, <Book: 九阳神功>, <Book: 九阴真经>]>
    <QuerySet [<Book: 葵花宝典>, <Book: 九阳神功>, <Book: 易筋经>, <Book: 九阴真经>, <Book: 红楼梦>, <Book: 论语>, <Book: 道德经>, <Book: 水浒传>, <Book: 西游记>, <Book: 独孤九剑>, <Book: 三国演义>]>
    <QuerySet [<Book: 三国演义>, <Book: 独孤九剑>, <Book: 西游记>, <Book: 水浒传>, <Book: 道德经>, <Book: 红楼梦>, <Book: 论语>, <Book: 九阴真经>, <Book: 易筋经>, <Book: 九阳神功>, <Book: 葵花宝典>]>
    <QuerySet [<Book: 葵花宝典>, <Book: 九阳神功>, <Book: 易筋经>, <Book: 九阴真经>, <Book: 红楼梦>, <Book: 论语>, <Book: 道德经>, <Book: 水浒传>, <Book: 西游记>, <Book: 独孤九剑>, <Book: 三国演义>]>
    西游记
    <QuerySet [<Book: 红楼梦>, <Book: 三国演义>, <Book: 水浒传>, <Book: 独孤九剑>, <Book: 葵花宝典>, <Book: 易筋经>, <Book: 道德经>, <Book: 论语>, <Book: 九阳神功>, <Book: 九阴真经>]> <class 'django.db.models.query.QuerySet'>
    <QuerySet [{'title': '红楼梦', 'price': Decimal('165.00')}, {'title': '三国演义', 'price': Decimal('199.00')}, {'title': '水浒传', 'price': Decimal('180.00')}, {'title': '西游记', 'price': Decimal('185.00')}, {'title': '独孤九剑', 'price': Decimal('190.00')}, {'title': '葵花宝典', 'price': Decimal('120.00')}, {'title': '易筋经', 'price': Decimal('140.00')}, {'title': '道德经', 'price': Decimal('176.00')}, {'title': '论语', 'price': Decimal('165.00')}, {'title': '九阳神功', 'price': Decimal('130.00')}, {'title': '九阴真经', 'price': Decimal('145.00')}]> <class 'django.db.models.query.QuerySet'>
    <QuerySet [('红楼梦', Decimal('165.00')), ('三国演义', Decimal('199.00')), ('水浒传', Decimal('180.00')), ('西游记', Decimal('185.00')), ('独孤九剑', Decimal('190.00')), ('葵花宝典', Decimal('120.00')), ('易筋经', Decimal('140.00')), ('道德经', Decimal('176.00')), ('论语', Decimal('165.00')), ('九阳神功', Decimal('130.00')), ('九阴真经', Decimal('145.00'))]> <class 'django.db.models.query.QuerySet'>
    <QuerySet [{'publisher': '清华出版社'}, {'publisher': '北大出版社'}, {'publisher': '北电出版社'}, {'publisher': '华山出版社'}, {'publisher': '黑木崖出版社'}, {'publisher': '少林出版社'}, {'publisher': '大宋出版社'}]> <class 'django.db.models.query.QuerySet'>
    [05/Apr/2020 12:37:56] "GET /app01/query_book HTTP/1.1" 200 1
    复制代码

    4.3 删除记录

    删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

    model_obj.delete()

    你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

    例如,下面的代码将删除 pub_date 是2018年的 Book 对象:

    Book.objects.filter(pub_date__year=2018).delete()

    设计url

    复制代码
    from django.urls import path,re_path
    from app01 import views
    urlpatterns = [
        path('add_book/', views.add_book),    #新增操作
        path('query_book/',views.query_book), #查询错做
        path('del_book/',views.del_book)      #删除操作
    ]
    复制代码

    视图函数

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
        return HttpResponse("新增成功")
    def query_book(request):
        #基于双线划线的模糊查询
        books = models.Book.objects.filter(price_in=[120,160,150])
        print(books)
        books = models.Book.objects.filter(price_range=[120, 160])
        print(books)
    
        return HttpResponse("查询成功")
    
    def del_book(request):
        pk = request.GET.get('pk')
        print(pk)
        #方式一使用对象的形式删除
        book_obj = models.Book.objects.filter(pk=pk).first()
        book_obj.delete()
        return HttpResponse("删除成功")
    复制代码

    访问http://127.0.0.1:8000/app01/del_book/?pk=3

    查看数据库

    mysql> select * from app01_book;

    复制代码
    +----+--------------+--------------+--------------------+--------+------------+
    | id | title        | author       | publisher          | price  | pub_date   |
    +----+--------------+--------------+--------------------+--------+------------+
    |  1 | 红楼梦       | 曹雪芹       | 清华出版社         | 165.00 | 2018-12-12 |
    |  2 | 三国演义     | 罗贯中       | 北大出版社         | 199.00 | 2018-12-23 |
    |  4 | 西游记       | 吴承恩       | 北大出版社         | 185.00 | 2019-02-12 |
    |  5 | 独孤九剑     | 风清扬       | 华山出版社         | 190.00 | 2019-01-15 |
    |  6 | 葵花宝典     | 东方不败     | 黑木崖出版社       | 120.00 | 2019-01-20 |
    |  7 | 易筋经       | 方丈大师     | 少林出版社         | 140.00 | 2019-01-23 |
    |  8 | 道德经       | 老子         | 北大出版社         | 176.00 | 2019-02-23 |
    |  9 | 论语         | 孔子弟子     | 北电出版社         | 165.00 | 2019-02-13 |
    | 10 | 九阳神功     | 张无忌       | 少林出版社         | 130.00 | 2018-01-23 |
    | 11 | 九阴真经     | 黄裳         | 大宋出版社         | 145.00 | 2017-03-23 |
    +----+--------------+--------------+--------------------+--------+------------+
    复制代码

    方法二

    视图函数

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat app01/views.py

    复制代码
    。。。。。。
    
    def del_book(request):
        pk = request.GET.get('pk')
        print(pk)
        #方式一使用对象的形式删除
        #book_obj = models.Book.objects.filter(pk=pk).first()
        #book_obj.delete()
        #方式二
        books = models.Book.objects.filter(pk=pk).delete()      #返回值是受影响的行数
        print(books)
        return HttpResponse("删除成功"
    复制代码

    在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:

    b = Book.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()

    要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

    Book.objects.all().delete()  

    访问http://127.0.0.1:8000/app01/del_book/?pk=4

    mysql> select * from app01_book;

    复制代码
    +----+--------------+--------------+--------------------+--------+------------+
    | id | title        | author       | publisher          | price  | pub_date   |
    +----+--------------+--------------+--------------------+--------+------------+
    |  1 | 红楼梦       | 曹雪芹       | 清华出版社         | 165.00 | 2018-12-12 |
    |  2 | 三国演义     | 罗贯中       | 北大出版社         | 199.00 | 2018-12-23 |
    |  5 | 独孤九剑     | 风清扬       | 华山出版社         | 190.00 | 2019-01-15 |
    |  6 | 葵花宝典     | 东方不败     | 黑木崖出版社       | 120.00 | 2019-01-20 |
    |  7 | 易筋经       | 方丈大师     | 少林出版社         | 140.00 | 2019-01-23 |
    |  8 | 道德经       | 老子         | 北大出版社         | 176.00 | 2019-02-23 |
    |  9 | 论语         | 孔子弟子     | 北电出版社         | 165.00 | 2019-02-13 |
    | 10 | 九阳神功     | 张无忌       | 少林出版社         | 130.00 | 2018-01-23 |
    | 11 | 九阴真经     | 黄裳         | 大宋出版社         | 145.00 | 2017-03-23 |
    +----+--------------+--------------+--------------------+--------+------------+
    复制代码

    调试输出

    4
    (1, {'app01.Book': 1})
    [05/Apr/2020 13:26:15] "GET /app01/del_book/?pk=4 HTTP/1.1" 200 12 

    4.4 修改表记录

    设计url

    复制代码
    from django.urls import path,re_path
    from app01 import views
    urlpatterns = [
        path('add_book/', views.add_book),    #新增操作
        path('query_book/',views.query_book), #查询错做
        path('del_book/',views.del_book),     #删除操作
        path('edit_book/',views.edit_book),    #编辑操作
    ] 
    复制代码

    视图函数

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
        return HttpResponse("新增成功")
    def query_book(request):
        #基于双线划线的模糊查询
        books = models.Book.objects.filter(price_in=[120,160,150])
        print(books)
        books = models.Book.objects.filter(price_range=[120, 160])
        print(books)
    
        return HttpResponse("查询成功")
    
    def del_book(request):
        pk = request.GET.get('pk')
        print(pk)
        #方式一使用对象的形式删除
        #book_obj = models.Book.objects.filter(pk=pk).first()
        #book_obj.delete()
        #方式二
        books = models.Book.objects.filter(pk=pk).delete()
        print(books)
        return HttpResponse("删除成功")
    
    def edit_book(request):
        pk = request.GET.get("pk")
        if request.method == "GET":
            book_obj = models.Book.objects.filter(pk=pk).first()
            return render(request,"edit_book.html",{"book_obj":book_obj})
    复制代码

    html模板文件

    root@darren-virtual-machine:~/PycharmProjects/mysite# cat templates/edit_book.html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>编辑数据</h3>
    
    <form action="" method="post">
        {% csrf_token %}
        <p>书名:<input type="text" name="title" value="{{ book_obj.title }}"></p>
        <p>作者:<input type="text" name="author" value="{{ book_obj.author }}"></p>
        <p>出版社:<input type="text" name="publisher" value="{{ book_obj.publisher }}"></p>
        <p>价格:<input type="text" name="price" value="{{ book_obj.price }}"></p>
        <p>出版时间:<input type="text" name="pub_date" value="{{ book_obj.pub_date|date:"Y-m-d" }}"></p>
        <input type="submit">
    </form>
    
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/app01/edit_book/?pk=5

    修改显示时间

    复制代码
    <form action="" method="post">
        {% csrf_token %}
        <p>书名:<input type="text" name="title" value="{{ book_obj.title }}"></p>
        <p>作者:<input type="text" name="author" value="{{ book_obj.author }}"></p>
        <p>出版社:<input type="text" name="publisher" value="{{ book_obj.publisher }}"></p>
        <p>价格:<input type="text" name="price" value="{{ book_obj.price }}"></p>
        <p>出版时间:<input type="text" name="pub_date" value="{{ book_obj.pub_date|date:"Y-m-d" }}"></p>
        <input type="submit">
    </form>
    复制代码

    刷新

     

    编辑操作

    方式一:

    通过修改实例对象的属性方式。注意:一定要对象.save()

    复制代码
    def edit_book(request):
        pk = request.GET.get("pk")
        if request.method == "GET":
            book_obj = models.Book.objects.filter(pk=pk).first()
            return render(request,"edit_book.html",{"book_obj":book_obj})
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            book_obj = models.Book.objects.filter(pk=pk).first()
            book_obj.price = price
            book_obj.save()
        return HttpResponse("编辑成功")
    复制代码

    访问http://127.0.0.1:8000/app01/edit_book/?pk=5并修改

    数据库查询

    复制代码
    +----+--------------+--------------+--------------------+--------+------------+
    | id | title        | author       | publisher          | price  | pub_date   |
    +----+--------------+--------------+--------------------+--------+------------+
    |  1 | 红楼梦       | 曹雪芹       | 清华出版社         | 165.00 | 2018-12-12 |
    |  2 | 三国演义     | 罗贯中       | 北大出版社         | 199.00 | 2018-12-23 |
    |  5 | 独孤九剑     | 风清扬       | 华山出版社         | 143.00 | 2019-01-15 |
    |  6 | 葵花宝典     | 东方不败     | 黑木崖出版社       | 120.00 | 2019-01-20 |
    |  7 | 易筋经       | 方丈大师     | 少林出版社         | 140.00 | 2019-01-23 |
    |  8 | 道德经       | 老子         | 北大出版社         | 176.00 | 2019-02-23 |
    |  9 | 论语         | 孔子弟子     | 北电出版社         | 165.00 | 2019-02-13 |
    | 10 | 九阳神功     | 张无忌       | 少林出版社         | 130.00 | 2018-01-23 |
    | 11 | 九阴真经     | 黄裳         | 大宋出版社         | 145.00 | 2017-03-23 |
    +----+--------------+--------------+--------------------+--------+------------+
    复制代码

    方式二:

    通过ORM提供的objects提供的方法 update来实现。

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    # Create your views here.
    def add_book(request):
        if request.method == "GET":
            return render(request,"add_book.html")
        else:
        #方式一:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            #book_obj = models.Book(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
            #book_obj.save()
        #方式二,推荐使用
            book_obj = models.Book.objects.create(title=title,author=author,publisher=publisher,price=price,pub_date=pub_date)
        return HttpResponse("新增成功")
    def query_book(request):
        #基于双线划线的模糊查询
        books = models.Book.objects.filter(price_in=[120,160,150])
        print(books)
        books = models.Book.objects.filter(price_range=[120, 160])
        print(books)
    
        return HttpResponse("查询成功")
    
    def del_book(request):
        pk = request.GET.get('pk')
        print(pk)
        #方式一使用对象的形式删除
        #book_obj = models.Book.objects.filter(pk=pk).first()
        #book_obj.delete()
        #方式二
        books = models.Book.objects.filter(pk=pk).delete()
        print(books)
        return HttpResponse("删除成功")
    
    def edit_book(request):
        pk = request.GET.get("pk")
        if request.method == "GET":
            book_obj = models.Book.objects.filter(pk=pk).first()
            return render(request,"edit_book.html",{"book_obj":book_obj})
        else:
        #方式二:
            title = request.POST.get("title")
            author = request.POST.get("author")
            publisher = request.POST.get("publisher")
            price = request.POST.get("price")
            pub_date = request.POST.get("pub_date")
            books = models.Book.objects.filter(pk=pk).update(price=price)    #返回影响事物的行数
            print(books)
        return HttpResponse("编辑成功")
    复制代码

    此外,update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。 

    访问 http://127.0.0.1:8000/app01/edit_book/?pk=6并修改

    查看数据库

    复制代码
    mysql> select * from app01_book;
    +----+--------------+--------------+--------------------+--------+------------+
    | id | title        | author       | publisher          | price  | pub_date   |
    +----+--------------+--------------+--------------------+--------+------------+
    |  1 | 红楼梦       | 曹雪芹       | 清华出版社         | 165.00 | 2018-12-12 |
    |  2 | 三国演义     | 罗贯中       | 北大出版社         | 199.00 | 2018-12-23 |
    |  5 | 独孤九剑     | 风清扬       | 华山出版社         | 143.00 | 2019-01-15 |
    |  6 | 葵花宝典     | 东方不败     | 黑木崖出版社       | 179.00 | 2019-01-20 |
    |  7 | 易筋经       | 方丈大师     | 少林出版社         | 140.00 | 2019-01-23 |
    |  8 | 道德经       | 老子         | 北大出版社         | 176.00 | 2019-02-23 |
    |  9 | 论语         | 孔子弟子     | 北电出版社         | 165.00 | 2019-02-13 |
    | 10 | 九阳神功     | 张无忌       | 少林出版社         | 130.00 | 2018-01-23 |
    | 11 | 九阴真经     | 黄裳         | 大宋出版社         | 145.00 | 2017-03-23 |
    +----+--------------+--------------+--------------------+--------+------------+
    复制代码

     编辑成功

    学习记录,小白一枚
  • 相关阅读:
    我们都可以把它放 Sidecar 容器中,这样微服务具备了 Super power,一种超能力
    DP 状态 DP 转移方程 动态规划解题思路
    完全二叉树 原因 完全二叉树最后一层节点靠左的原因
    延时任务最佳实践方案总结
    b+ 树 只存储 索引
    埋点质量保障体系建设
    linux命令重定向>、>>、 1>、 2>、 1>>、 2>>、 <
    卡特兰数
    python 使用函数名的字符串调用函数(4种方法)_black-heart的专栏-CSDN博客 https://blog.csdn.net/mrqingyu/article/details/84403924
    12 | 服务注册与发现如何满足服务治理
  • 原文地址:https://www.cnblogs.com/wangsirde0428/p/14322878.html
Copyright © 2011-2022 走看看