Python学习之路—2018/6/29

Python学习之路—2018/6/29

1.跨表查询

跨表查询:

  1. 基于对象查询
  2. 基于双下划线查询
  3. 聚合和分组查询
  4. F与Q查询

F查询

过滤器只能讲字段值与常量进行比较,如果需要用到与字段值进行比较则需要用到F查询,F查询还支持与常量之间的加减乘除的运算。数据:

# 查询评论数大于阅读数的书籍
>>> Book.objects.filter(comment_count__gt=F("read_count"))
<QuerySet [<Book: 斗破苍穹>, <Book: 吞噬星空>]>

# 将所有书的价格提高10元
>>> Book.objects.all().update(price=F("price")+10)

Q查询

过滤器中可以用逗号起到“和”的作用,如果想要用“或”的操作就需要用到Q查询

# 查询书籍名为斗破苍穹或者价格为130的
>>> Book.objects.filter(Q(title="斗破苍穹") | Q(price=130))
<QuerySet [<Book: 坏蛋是怎样炼成的>, <Book: 斗破苍穹>, <Book: 武动乾坤>]>

2.基于多表的图书管理系统

主要有图书的增删改查四个功能,对应设置四个视图函数分别为add()、query()、edit()、delete()

2.1 创建模型

分别有作者表(author),作者详细信息表(authordetail),图书表(book),出版社表(publish)以及作者图书关联表(book_authors)。

其中因为一个作者只有一个详细信息,所以作者表(author)与作者详细信息表(authordetail)是一对一关系;一个出版社可以出版多本书,所以图书表(book)与出版社表(publish)是一对多关系;一个出版社可以出版多个作者的书籍,而一位作者可以签约多个出版社,所以图书表(book)与作者表(author)是多对多关系。

models.py

from django.db import models


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # 与AuthorDetail建立一对一关系
    author_detail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class AuthorDetail(models.Model):
    aid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    pid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Book(models.Model):
    bid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)

    # 与Publish建立一对多关系,外键字段建立在多的一方
    publish = models.ForeignKey(to="Publish", to_field="pid", on_delete=models.CASCADE)
    """
        publish_id INT,
        FOREIGN KEY(publish_id) REFERENCES publish(pid)
    """

    # 与Author建立多对多关系
    authors = models.ManyToManyField(to="Author")
    """
        CREATE TABLE book_author(
            id INT PRIMARY KEY AUTO_INCREMENT,
            book_id INT,
            author_id INT,
            FOREIGN KEY(book_id) REFERENCES Book(bid),
            FOREIGN KEY(author_id) REFERENCES Author(nid),
        )
    """

    def __str__(self):
        return self.title

2.2 配置static

为了使static文件夹下面的css、js文件生效,需要将static路径加入到STATICFILES_DIRS中

settings.py

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]

2.3 建立视图函数

views.py

from django.shortcuts import render, HttpResponse, redirect
from .models import *

def add(request):
    pub_list = Publish.objects.all()
    author_list = Author.objects.all()
    if request.method == "GET":
        return render(request, "add.html", locals())
    elif request.method == "POST":
        # 获取输入的值
        title = request.POST.get("title")
        price = request.POST.get("price")
        pub_date = request.POST.get("pub_date")
        publish = request.POST.get("publish")
        authors_list = request.POST.getlist("author")  # getlist适用于多选的
        
        # orm添加数据
        Book.objects.create(title=title, publishDate=pub_date, price=price, publish_id=publish)
        book = Book.objects.get(title=title)
        book.authors.add(*authors_list)
        
        # 添加提交后回到图书界面
        return redirect("/book")


def book(request):
    book_list = Book.objects.all()
    return render(request, "book.html", locals())


def delete(request, bid):
    Book.objects.get(bid=bid).delete()
    return redirect("/book")


def edit(request, bid):
    book_obj = Book.objects.filter(bid=bid)
    books = Book.objects.get(bid=bid)
    pub_list = Publish.objects.all()
    author_list = Author.objects.all()
    if request.method == "GET":
        return render(request, "edit.html", locals())
    elif request.method == "POST":
        title = request.POST.get("title")
        price = request.POST.get("price")
        pub_date = request.POST.get("pub_date")
        authors_list = request.POST.getlist("author")

        book_obj.update(title=title, price=price, publishDate=pub_date)
        books.authors.set(authors_list)

        return redirect("/book")

2.4 模板层

book.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>book</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
    <style type="text/css">
        .table-bordered>thead>tr>th, .table-bordered>tbody>tr>td{
            text-align: center;
            line-height: 33px;
        }
    </style>
</head>
<body>
    <h3>查看书籍</h3>

    <div class="container">
        <div class="row">
            <div class="col-md-8 col-lg-offset-2">
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>名称</th>
                            <th>价格</th>
                            <th>出版日期</th>
                            <th>出版社</th>
                            <th>作者</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        {# 根据传入的book_list,循环添加表数据 #}
                        {% for book in book_list %}
                            <tr>
                                <td>{{ book.title }}</td>
                                <td>{{ book.price }}</td>
                                <td>{{ book.publishDate|date:"Y-m-d" }}</td>
                                <td>{{ book.publish }}</td>
                                <td>{% for i in book.authors.all %}
                                        {% if forloop.last %}
                                            <span>{{ i.name }}</span>
                                        {% else %}
                                            <span>{{ i.name }}</span>,
                                        {% endif %}
                                    {% endfor %}
                                </td>
                                <td>
                                    <a class="btn btn-primary" href="/edit/{{ book.bid }}">编辑</a>  {# 传入book ID参数,便于在数据库中的表寻找数据后进行编辑和删除功能 #}
                                    <a class="btn btn-danger" href="/delete/{{ book.bid }}">删除</a>
                                </td>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
                <a class="btn btn-default" href="/add">添加书籍</a>
            </div>
        </div>
    </div>
</body>
</html>

add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add</title>
    <link rel="stylesheet" href="/static/bootstrap.min.css">
</head>
<body>
    {% block h3 %}
    <h3>添加书籍</h3>
    {% endblock %}

    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
                <form action="" method="post">
                    {% csrf_token %}
                    <div class="form-group">
                        <label>名称</label>
                        {% block title %}
                        <input class="form-control" type="text" name="title">
                        {% endblock title %}
                    </div>
                    <div class="form-group">
                        <label>价格</label>
                        {% block price %}
                        <input class="form-control" type="text" name="price">
                        {% endblock price %}
                    </div>
                    <div class="form-group">
                        <label>出版日期</label>
                        {% block pub_late%}
                        <input class="form-control" type="date" name="pub_date">
                        {% endblock pub_late %}
                    </div>
                    <div class="form-group">
                        <label>出版社</label>
                        <select class="form-control" name="publish">
                            {% for i in pub_list %}
                                {% block publish %}
                                    <option value="{{ i.pk }}">{{ i.name }}</option>
                                {% endblock %}
                            {% endfor %}
                        </select>
                    </div>
                    <div class="form-group">
                        <label>作者</label>
                        <select class="form-control" name="author" multiple>
                            {% for author in author_list %}
                                {% block author %}
                                    <option value="{{ author.pk }}">{{ author.name }}</option>
                                {% endblock %}
                            {% endfor %}
                        </select>
                    </div>
                    <input type="submit" class="btn btn-default">
                </form>
            </div>
        </div>
    </div>
</body>
</html>

edit.html

继承add.html,重写block里的内容

{% extends "add.html" %}

{% block h3 %}
    <h3>编辑书籍</h3>
{% endblock %}

{% block title %}
   {{ book_obj.title }}
    <input class="form-control" type="text" name="title" value="{{ books.title }}">
{% endblock %}

{% block price %}
    <input class="form-control" type="text" name="price" value="{{ books.price }}">
{% endblock %}

{% block pub_late%}
    <input class="form-control" type="date" name="pub_date" value="{{ books.publishDate|date:'Y-m-d'}}">
{% endblock %}

{% block publish %}
    {# 通过传入的book出版社与所有出版社名字进行比较,相同的添加selected属性,起到编辑时的默认选中功能 #}
    {% if books.publish.name == i.name %}
        <option value="{{ i.pk }}" selected>{{ i.name }}</option>
    {% else %}
        <option value="{{ i.pk }}">{{ i.name }}</option>
    {% endif %}
{% endblock %}

{% block author %}
    {% if author in books.authors.all %}
        <option value="{{ author.pk }}" selected>{{ author.name }}</option>
    {% else %}
        <option value="{{ author.pk }}">{{ author.name }}</option>
    {% endif %}
{% endblock %}

2.5 路由层

urls.py

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('add/', views.add),
    path('book/', views.book),
    re_path(r'^delete/(\d+)', views.delete),
    re_path(r'^edit/(\d+)', views.edit)
]

首先在浏览器中输入127.0.0.1:8080/book,到展示图书界面,接下来便可以操作添加、编辑、删除功能了。

猜你喜欢

转载自www.cnblogs.com/ExBurner/p/9245448.html