zoukankan      html  css  js  c++  java
  • python 之 Django框架(APP和ORM的使用)

    12.3 APP

    12.31 创建APP

    一个Django项目可以分为很多个APP,用来隔离不同功能模块的代码

    用命令行创建一个APP:

    python3 manage.py startapp app01

    创建好APP,记得告诉Django,app的名字,在settings.py中添加:

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

    12.32 Django中的ORM

    Django项目使用MySQL数据库

    1.在Django项目的settings.py文件中,配置数据库连接信息:告诉Django连接哪个数据库

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": "db6",              # 需要自己手动先创建数据库
            "USER": "root",
            "PASSWORD": "",
            "HOST": "127.0.0.1",
            "PORT": 3306
        }
    }

    2.Django默认使用的是 MySQLdb模块 连接数据库,但 MySQLdb在python3中不支持,所以:

    在与Django项目同名的文件夹的__init__.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库代替MySQLdb:

    import pymysql
    pymysql.install_as_MySQLdb()

    3.在app/models.py文件中定义类,一定要继承models.Model

    from django.db import models
    ​
    class User(models.Model):
        id = models.AutoField(primary_key=True)  # 自增主键
        name = models.CharField(max_length=16)   # varchar(16)
        pwd = models.CharField(max_length=128)   # varchar(128)
    # 出版社    
    class Publisher(models.Model):
        id = models.AutoField(primary_key=True)   # 自增主键
        name = models.CharField(max_length=16)    # varchar(16) # 出版社名称
    #def __str__(self):                     #定义__str__是在打印表的对象时可以看到每一行的字段
        #    return (self.id,self.name)
    # 书籍
    class Book(models.Model):
        id = models.AutoField(primary_key=True)        # 自增的主键
        title = models.CharField(max_length=32)        # 书籍名称 varchar(32)
        publisher = models.ForeignKey(to="Publisher")  # 外键关联Publisher这张表
    # 作者
    class Author(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=16)
        books = models.ManyToManyField(to="Book")
        # ORM创建多对多字段,会自动在数据库中创建第三张表 id Author_id、Book_id

    用命令行执行创建表的操作:

    1. python3 manage.py makemigrations    --> 将models.py的修改登记到小本本上
    2. python3 manage.py migrate           --> 将修改翻译成SQL语句,去数据库执行

    4.在app/views.py文件中写urls.py中 /publisher_list/ 的对应函数publisher_list/add_publisher/的对应函数add_publisher

    urls.py中的对应关系:

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    ​
    # 对应关系
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^publisher_list/', views.publisher_list),       # 展示出版社列表
        url(r'^add_publisher/', views.add_publisher),        # 添加出版社
        url(r'^delete_publisher/', views.delete_publisher),  # 删除出版社
        url(r'^edit_publisher/', views.edit_publisher),      # 编辑出版社
        url(r'^book_list/', views.book_list),               # 书籍列表
        url(r'^add_book/', views.add_book),                 # 添加书籍
        url(r'^delete_book/', views.delete_book             # 删除书籍
        url(r'^edit_book/', views.edit_book),               # 编辑书籍
        url(r'^author_list/', views.author_list),            # 作者列表
        url(r'^add_author/', views.add_author),             # 添加作者
        url(r'^delete_author/', views.delete_author),       # 删除作者
        url(r'^edit_author/', views.edit_author),           # 编辑作者
        url(r'^$', views.publisher_list)                   # 以上对应关系都找不到,就匹配出版社页面
    ]

    app/views.py:

    12.321 有关出版社的函数逻辑
    from django.shortcuts import HttpResponse, render, redirect
    from app01 import models
    # 显示出版社列表
    def publisher_list(request):
        ret = models.Publisher.objects.all()    # 从数据库中取出所有的数据对象列表
        #print(ret)
        return render(request, "publisher_list.html", {"publisher_list": ret})
    ​
    #添加出版社函数
    def add_publisher(request):     # 根据请求方法的不同,要做不同的事情,add_publisher.html使用POST方法
        if request.method == "POST":#request.method获取的是请求的方法(GET、POST...必须是大写)
            #request.POST(字典)获取POST提交过来的全部数据
            new_publisher_name = request.POST.get("publisher_name")
            models.Publisher.objects.create(name=new_publisher_name)#创建对象并封装属性(插入一行数据)
            #或者自己用类实例化一个对象:obj=models.Publisher(name=new_publisher_name) obj.save()
            #让用户跳转到publisher_list.html,显示新增数据后的publisher_list.html页面
            return redirect("/publisher_list/")
        return render(request, "add_publisher.html")
    ​
    # 删除出版社函数
    def delete_publisher(request):
        #print(request.method)
        #print(request.GET)
        delete_id = request.GET.get("id")              #拿到用户要删除的出版社的id值
        #print(delete_id)
        obj = models.Publisher.objects.get(id=delete_id)#根据id值得到对象
        obj.delete()                                 #将数据删除
        return redirect("/publisher_list/")            #让用户重新访问publisher_list.html更新页面
    # 编辑出版社的函数
    def edit_publisher(request):
     #edit_id = request.GET.get("id")如果用户提交使用URL拼接id,那么从URL里面取id参数request.GET.get("id")
        if request.method == "POST":    #如果是post请求,表示用户已经编辑好了,向服务端提交修改后的新数据
            edit_id = request.POST.get("edit_id")  # 拿到已经修改的出版社id
            new_name = request.POST.get("name")    # 拿到修改之后的出版社的名字
            edit_obj = models.Publisher.objects.get(id=edit_id)#通过id找到数据行对象
            edit_obj.name = new_name
            edit_obj.save()                      #保存修改,提交数据库
            return redirect("/publisher_list/")    # 修改成功,让用户跳转到出版社列表页面,更新页面
    #如果不是post请求,则返回edit_publisher.html页面给用户修改出版社
        edit_id = request.GET.get("id")                #先获取编辑的出版社的ID值
        obj = models.Publisher.objects.get(id=edit_id)  #根据id值去数据库找对应的行数据对象
        return render(request, "edit_publisher.html", {"publisher": obj})#将数据想要编辑的出版社显示出来,等待用户编辑

    templates/publisher_list.html:

    <body>
    <table border="1">
        <thead>
        <tr>
            <th>#</th>
            <th>出版社名称</th>
        </tr>
        </thead>
        <tbody>
        {% for publisher in publisher_list %}
        <tr>
            <td>{{ publisher.id }}</td>     #{{ forloop.counter }计数表格中的数据条数,从而删除后更新id
            <td>{{ publisher.name }}</td>
            <td class="text-center">
                <a class="btn btn-info btn-sm" href="/edit_publisher/?id={{ publisher.id }}">
                <i class="fa fa-pencil fa-fw" aria-hidden="true"></i> 编辑 </a>
                <a class="btn btn-danger btn-sm" href="/delete_publisher/?id={{ publisher.id }}">
                <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除 </a>
            </td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
    </body>
    View Code

    templates/add_publisher.html:

    <body>
    <h1>添加新的出版社</h1>
    <form action="/add_publisher/" method="post">
        <input type="text" name="publisher_name">
        <input type="submit" value="提交">
    </form>
    </body>
    View Code

    templates/edit_publisher.html:

    #如果#action="/edit_publisher/?id={{ publisher.id }}"那么就从URL中用request.GET.get()取id参数
    <form class="form-horizontal" action="/edit_publisher/" method="post">
        <input type="text" name="edit_id" value="{{ publisher.id }}" class="hide">#将获取id的input框隐藏
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">出版社名称</label>
            <div class="col-sm-9">
                <input type="text" class="form-control" id="inputEmail3" name="name"
                       placeholder="出版社名称" value="{{ publisher.name }}">#提交出版社名称
            </div>
        </div><div class="form-group">
            <div class="col-sm-offset-3 col-sm-9">
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
    View Code
    12.322 有关书籍的函数逻辑
    from django.shortcuts import HttpResponse, render, redirect
    from app01 import models
    # 书籍列表函数
    def book_list(request):
        ret = models.Book.objects.all()                          #去数据库查询所有的书籍对象
        return render(request, "book_list.html", {"book_list": ret})#将数据填充到页面上,发送给客户端
    # 添加书籍函数
    def add_book(request):
        if request.method == "POST":                #如果是POST请求表示用户新添加了一本书籍和关联的出版社
            book_name = request.POST.get("book_name")       # 添加新书籍的名称
            publisher_id = request.POST.get("publisher_id")  # 添加新书籍关联的出版社id值
            models.Book.objects.create(title=book_name, publisher_id=publisher_id)
            
            #publisher_obj = models.Publisher.objects.get(id=publisher_id)#根据id值先找到关联的出版社对象
            #models.Book.objects.create(title=book_name, publisher=publisher_obj)
            return redirect("/book_list/")                 # 创建成功,让用户跳转到书籍列表页面,刷新数据
    # 取到所有的出版社数据,在页面上渲染成select标签,供用户选择
        ret = models.Publisher.objects.all()
        return render(request, "add_book.html", {"publisher_list": ret})
    ​
    # 删除书籍的函数
    def delete_book(request):
        delete_book_id = request.GET.get("id")            # 从URL里面取到要删除的书籍的ID
        models.Book.objects.get(id=delete_book_id).delete()# 去数据库中删除
        return redirect("/book_list/")                    # 删除成功,跳转到书籍列表页面,刷新数据
    # 编辑书籍的函数
    def edit_book(request):  
        if request.method == "POST":                 # 如果是POST请求 表名是用户修改好了数据,向后端提交了
            new_book_title = request.POST.get("book_title") # 取用户提交过来的数据
            new_publisher_id = request.POST.get("publisher_id")
            
            book_id = request.GET.get("id")              #获取URL中的当前编辑图书的id
            book_obj = models.Book.objects.get(id=book_id)# 根据id取出要编辑的书籍对象
            
            book_obj.title = new_book_title
            book_obj.publisher_id = new_publisher_id
            book_obj.save()                            # 将修改保存到数据库
            return redirect("/book_list/")              # 修改完之后让用户跳转回书籍列表页面
    # 返回一个让用户编辑数据的页面
        edit_book_id = request.GET.get("id")                    # 取编辑的书籍的id值
        edit_book_obj = models.Book.objects.get(id=edit_book_id) # 取到要编辑的书籍对象
        publisher_list = models.Publisher.objects.all()          # 去数据库查询目前所有的出版社数据
        return render(request,"edit_book.html",{"book": edit_book_obj,"publisher_list":publisher_list})

    templates/book_list.html:

    <table class="table table-striped table-bordered">
        <thead>
        <tr>
            <th>序号</th>
            <th>书籍名称</th>
            <th>出版社名称</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for book in book_list %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.publisher.name}}</td># book.publisher拿到的是外键(id)关联的出版社的行数据对象
                <td class="text-center">
                    <a class="btn btn-info btn-sm" href="/edit_book/?id={{ book.id }}">
                    <i class="fa fa-pencil fa-fw"  aria-hidden="true"></i> 编辑 </a>
                    <a class="btn btn-danger btn-sm" href="/delete_book/?id={{ book.id }}">
                    <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i> 删除 </a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    View Code

    templates/add_book.html:

    <form class="form-horizontal" action="/add_book/" method="post">
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">书籍名称</label>
            <div class="col-sm-9"><input type="text" class="form-control" id="inputEmail3" name="book_name" placeholder="书籍名称">
            </div>
        </div>
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">出版社名称</label>
            <div class="col-sm-9">
                <select class="form-control" name="publisher_id">
                    {% for publisher in publisher_list %}
                    <option value="{{ publisher.id }}"> {{ publisher.name }}
                    </option>
                    {% endfor %}
                </select>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-3 col-sm-9"><button type="submit" class="btn btn-default">提交</button> </div>
        </div>
    </form>
    View Code

    templates/edit_book.html:

    #action=""此处使用默认URL,即继承之前的/edit_book/?id={{ book.id }}
    #或者#action="/edit_publisher/?id={{ publisher.id }}"那么就从URL中用request.GET.get()取id参数
    <form class="form-horizontal" action="" method="post">
        #隐藏要编辑的书,发送id到后端,为了在后端找到要修改的图书,方便修改
        #<input type="text" value="{{ book.id }}" name="book_id" class="hide">
        
        #预先在输入框和下拉框显示要修改的图书名和出版社名
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">书籍名称</label>
            <div class="col-sm-9">
                <input type="text" class="form-control" id="inputEmail3" name="book_title" value="{{ book.title }}" placeholder="书籍名称">
            </div>
        </div>
        
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">出版社名称</label>
            <div class="col-sm-9">
            
                <select class="form-control" name="publisher_id">
                 # 如果当前循环到的出版社和书关联的出版社相等,则添加selected,表示预先选中的
                    {% for publisher in publisher_list %}   
                        {% if publisher == book.publisher %}
                            <option value="{{ publisher.id }}" selected>{{ publisher.name }}</option>
                        {% else %}
                            <option value="{{ publisher.id }}">{{ publisher.name }}</option>
                        {% endif %}
                    {% endfor %}                      
                </select>
                
            </div>
        </div><div class="form-group">
            <div class="col-sm-offset-3 col-sm-9">
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
    View Code
    12.323 有关作者的函数逻辑
    # 作者列表函数
    def author_list(request):
        authors = models.Author.objects.all()    # 从数据库中查询所有的作者数据,在页面上展示出来
        # author_obj = models.Author.objects.get(id=1)
        # print(author_obj.books.all())            表示id=1的作者写的所有书的对象
        return render(request, "author_list.html", {"author_list": authors})
    
    # 添加作者函数
    def add_author(request):
        if request.method == "POST":            
            new_author_name = request.POST.get("author_name") # 拿到新的作者姓名    
            models.Author.objects.create(name=new_author_name)# 去数据库中创建一个新的作者记录
            return redirect("/author_list/")                  # 创建好作者之后,让用户跳转到作者列表页面
        # 返回一个页面,让用户填写新的作者信息
        return render(request, "add_author.html")
    
    # 删除作者函数
    def delete_author(request):
        delete_author_id = request.GET.get("id")              # 从URL里面取到要删除的作者的ID    
        models.Author.objects.get(id=delete_author_id).delete()# 去数据库中找到该作者并删除
        return redirect("/author_list/")                      # 删除成功后 跳转回作者列表页面
    
    # 编辑作者函数
    def edit_author(request):
        if request.method == "POST":                  # 如果发送的是POST请求,应该拿到用户提交的数据      
            edit_author_id = request.POST.get("author_id")       # 编辑的作者id
            # 取新名字和新的书籍id
            new_author_name = request.POST.get("author_name")
            new_book_ids = request.POST.getlist("book_ids")
            # 如果提交过来的数据是多个值(多选的select/多选的checkbox)则使用getlist取列表
            # print(request.POST)
            # print(edit_author_id, new_author_name, new_book_ids)
     
            # 去编辑作者以及对应的书籍
            edit_author_obj = models.Author.objects.get(id=edit_author_id)# 拿到编辑的作者对象
            edit_author_obj.name = new_author_name                        # 修改作者姓名
            edit_author_obj.save()
            # 修改作者写的书籍
            edit_author_obj.books.set(new_book_ids)            #通过新书id更换作者对应的书籍,并提交数据库
            return redirect("/author_list/")                # 修改完成之后,跳转到作者列表页面
    
        # 返回一个页面,让用户编辑
        edit_author_id = request.GET.get("id")                      # 从URL里面取到要编辑作者的id参数
        edit_author_obj = models.Author.objects.get(id=edit_author_id)# 取到要编辑的作者对象
        book_list = models.Book.objects.all()                        # 获取所有的书籍对象信息
        return render(request,"edit_author.html",{"author": edit_author_obj, 

    templates/author_list.html:

     <div class="col-md-3 col-sm-6 pull-right add-btn">
        <button data-target="#myModal" data-toggle="modal" class="btn btn-success pull-right">新增
        </button>
        <a href="/add_author/" class="btn btn-info pull-right">新页面添加 </a>
     </div><table class="table table-striped table-bordered">
        <thead>
        <tr>
            <th>序号</th>
            <th>作者姓名</th>
            <th>著作</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for author in author_list %}#{"author_list": authors}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ author.name }}</td>
                <td>                               #在这一列展示这个作者关联的所有的书籍
                    {% for book in author.books.all %}#书籍对象的列表
                        {% if forloop.last %}
                            《{{ book.title }}》
                        {% else %}
                            《{{ book.title }}》,
                        {% endif %}
                    {% empty %}
                        暂无著作
                    {% endfor %}
                </td>
                <td class="text-center">
                    <a class="btn btn-info btn-sm" href="/edit_author/?id={{ author.id }}">
                    <i class="fa fa-pencil fa-fw" aria-hidden="true"></i>编辑 </a>
                    <a class="btn btn-danger btn-sm" href="/delete_author/?id={{ author.id }}">
                    <i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除 </a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    View Code

    templates/add_author.html:

    <form class="form-horizontal" action="/add_author/" method="post">
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">作者姓名</label>
            <div class="col-sm-9">
                <input type="text" class="form-control" id="inputEmail3" name="author_name"
                       placeholder="作者姓名">
            </div>
        </div><div class="form-group">
            <div class="col-sm-offset-3 col-sm-9">
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
    View Code

    templates/edit_author.html:

    <form class="form-horizontal" action="" method="post">#action=""默认转到当前URL
        <input type="text" value="{{ author.id }}" name="author_id" class="hide">
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">作者姓名</label>
            <div class="col-sm-9">
                <input type="text" class="form-control" id="inputEmail3" name="author_name"
                       value="{{ author.name }}" placeholder="作者姓名">
            </div>
        </div>
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-3 control-label">著作</label>
            <div class="col-sm-9">
                <select class="form-control" name="book_ids" multiple>
                    {% for book in book_list %}            #book_list 所有的书籍对象
                        #author:要编辑的作者,author.books.all:要编辑的作者的所有书籍对象
                        {% if book in author.books.all %}   # 如果当前这本书在作者写的书里面
                            <option value="{{ book.id }}" selected>{{ book.title }}</option>
                        {% else %}
                            <option value="{{ book.id }}">{{ book.title }}</option>
                        {% endif %}
                    {% endfor %}
                </select>
            </div>
        </div><div class="form-group">
            <div class="col-sm-offset-3 col-sm-9">
                <button type="submit" class="btn btn-default">提交</button>
            </div>
        </div>
    </form>
    View Code
  • 相关阅读:
    HDU-2896 病毒侵袭 字符串问题 AC自动机
    HDU-2222 Keywords Search 字符串问题 AC自动机
    pyhton3 logging模块
    pyhton3 sys模块
    pyhton3 hashlib模块
    pyhton3 os模块
    pyhton3 time模块
    pyhton3 random模块
    变种XSS:持久控制
    富文本存储型XSS的模糊测试之道
  • 原文地址:https://www.cnblogs.com/mylu/p/11415113.html
Copyright © 2011-2022 走看看