1. 程式人生 > 實用技巧 >Django - 圖書管理系統

Django - 圖書管理系統

一、出版社增刪改查

url

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^login/$', views.login),
    url(r'^index/$', views.index),
    url(r'^press_list/$', views.press_list),  # 展示出版社
    url(r'^add_press/$', views.add_press),  # 添加出版社
    url(r
'^delete_press/$', views.delete_press), # 刪除出版社 url(r'^edit_press/$', views.edit_press), # 編輯出版社 ]
View Code

models

from django.db import models



class User(models.Model):
    id = models.AutoField(primary_key=True)   # -> 建立一個自增的ID列作為主鍵
    email = models.CharField(max_length=24)  # -> varchar(32
) pwd = models.CharField(max_length=16) # -> varchar(32) def __str__(self): return self.email # 出版社表 class Press(models.Model): id = models.AutoField(primary_key=True) # id主鍵 name = models.CharField(max_length=32) # 出版社名稱 def __str__(self): return '<這是一個出版社物件,它的名字是:{}>
'.format(self.name)
View Code

views

from django.shortcuts import render, HttpResponse, redirect
from app01.models import User, Press


def login(request):
    # print(request.GET)
    # print('-' * 120)
    error_msg = ''
    # 需要判斷
    # 根據請求的方法來做判斷
    if request.method == 'POST':
        # 如果是第二次來,表示填完了要給我發資料了             --> POST
        email = request.POST.get('email')
        pwd = request.POST.get('pwd')
        print(email, pwd)
        # if email == '[email protected]' and pwd == '123':
        # 從資料庫查詢有沒有這個使用者
        # select * from app01_user where email='[email protected]' and pwd='123';
        ret = User.objects.filter(email=email, pwd=pwd)
        print(type(ret[0]))
        print(ret[0].id, ret[0].email, ret[0].pwd)
        if ret:
            # 登入成功,跳轉index
            return redirect('/index/')
        else:
            # 登入失敗
            # 提示使用者郵箱或密碼錯誤
            error_msg = '郵箱或密碼錯誤'
    # 如果你是第一次來,是跟我要一個登入頁面用來填寫資料的  --> GET
    return render(request, 'login.html', {'error_msg': error_msg})





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


# 出版社列表處理函式
def press_list(request):
    # 1. 去資料庫查所有的出版社
    ret = Press.objects.all().order_by('id')
    # print(ret)
    # print(ret[0])
    # print(ret[0].name)
    # 2. 在HTML頁面上展示出來
    return render(request, 'press_list.html', {'kangchen': ret})


# 添加出版社的處理函式
def add_press(request):
    if request.method == 'POST':
        # 表示使用者填寫完了,要給我發資料
        # 1. 取到使用者填寫的出版社資料
        press_name = request.POST.get('name')
        # 2. 將資料新增到資料庫中
        Press.objects.create(name=press_name)
        # 3. 跳轉到出版社列表頁面
        return redirect('/press_list/')

    # 1. 返回一個新增頁面,讓使用者在上面填寫新的出版社的資訊
    return render(request, 'add_press.html')


# 刪除出版社處理函式
def delete_press(request):
    # 1. 獲取要刪除的出版社ID
    delete_id = request.GET.get('id')
    print('-' * 120)
    print(delete_id)
    print('*' * 120)
    # 2. 根據id去資料庫刪除對應的資料行
    Press.objects.filter(id=delete_id).delete()
    # 3. 讓使用者再去訪問以下出版社列表頁
    return redirect('/press_list/')


# 編輯出版社
def edit_press(request):
    # 1. 從URL中獲取要編輯的出版社的id
    edit_id = request.GET.get('id')

    if request.method == 'POST':
        # 使用者修改完出版社資料給我發過來了
        # 1.取出使用者編輯之後的資料
        new_name = request.POST.get('name')
        # 2. 去資料庫修改對應的資料
        # 2.1 先找對應的資料:出版社物件
        edit_press_obj = Press.objects.get(id=edit_id)
        # 2.2 修改出版社的名稱
        edit_press_obj.name = new_name
        # 2.3 將修改同步到資料庫
        edit_press_obj.save()
        # 3. 讓使用者再去訪問出版社列表頁
        return redirect('/press_list/')

    # 2. 獲取該出版社的資訊
    # ret = Press.objects.filter(id=edit_id)  # -->[Press obj, ]
    # print(ret)
    ret = Press.objects.get(id=edit_id)  # --> Press Obj, get()有且只能找到一個物件,否則就報錯
    print(ret)
    # 3. 在頁面上展示出來
    return render(request, 'edit_press.html', {'press_obj': ret})
View Code

templates:

1.press_list.html

<body>

<a href="/add_author/">新增作者</a>
<table border="1">
    <thead>
    <tr>
        <th>序號</th>
        <th>作者id</th>
        <th>作者姓名</th>
        <th>作者作品</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for author in author_list %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ author.id }}</td>
            <td>{{ author.name }}</td>
            <td style="text-align: center">
                {% for book in author.books.all %}
                    {% if forloop.last %}
                        《{{ book.title }}》
                    {% else %}
                        《{{ book.title }}》,
                    {% endif %}
                {% empty %}
                    暫無作品
                {% endfor %}
            </td>
        <td>
            <a href="/delete_author/?kangchen={{ author.id }}&age=22">刪除</a>
            <a href="/edit_author/?id={{ author.id }}">編輯</a>
        </td>
        </tr>
    {% endfor %}
    </tbody>
</table>
</body>
View Code

2.add_press.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>添加出版社</title>
</head>
<body>

<form action="/add_press/" method="post">
    <input type="text" name="name">
    <input type="submit">
</form>

</body>
</html>
View Code

3.edit_press_list.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>編輯出版社</title>
</head>
<body>

<h1>編輯出版社</h1>
<form action="/edit_press/?id={{ press_obj.id }}" method="post">
    <input type="text" name="name" value="{{ press_obj.name }}">
    <input type="submit">
</form>

</body>
</html>
View Code

總結:

1. 圖書管理系統之出版社的增刪改查
		1. 表結構設計
			1. 出版社
				id  name 
			2. 作者
				id  name  
			3. 書
				id  title 出版社_id
			4. 作者_書_關係表
				id 書_id 作者_id
	
		2. ORM版增刪改查
			1. ORM的語句
				1. 類名.objects.all()		    	  --> 返回一個列表
				2. 類名.objects.filter()              --> 返回一個列表
				3. 類名.objects.get()                 --> 返回一個物件
				
				4. 類名.objects.create(name='')       --> 建立一個物件,返回的就是剛建立的物件
				
				5. 類名.objects.filter(id=).delete()  --> 刪除
				
				6. obj = 類名.objects.get(id='')
				   obj.name = '新值'                  --> 修改物件的屬性(修改資料行某個欄位的值)
				   obj.save()                         --> 把修改同步到資料庫
	
		3. Django 模板語言
		
			1. for迴圈
				{% for i in ret %}
					{{ i }}
					{{ forloop.counter }}             --> for迴圈從1開始計數
					{{ forloop.counter0 }}            --> for迴圈從0開始計數
 				{% endfor %}

  

二、書籍增刪改查(一對多)

url

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [

    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),  # 編輯書籍
]
View Code

models

from django.db import models

# 出版社表
class Press(models.Model):
    id = models.AutoField(primary_key=True)  # id主鍵
    name = models.CharField(max_length=32)  # 出版社名稱

    def __str__(self):
        return '<這是一個出版社物件,它的名字是:{}>'.format(self.name)


# 書
class Book(models.Model):
    id = models.AutoField(primary_key=True)  # 自增id主鍵
    title = models.CharField(max_length=30)  # 書名
    # Django 1.11 預設就是級聯刪除, Django 2.0之後必須指定on_delete
    # to=關聯的表名
    press = models.ForeignKey(to='Press', on_delete=models.CASCADE)
View Code

views

# 書籍展示函式
def book_list(request):
    # 1. 查詢所有的書籍資料
    data = Book.objects.all()
    # 取到第一本書物件
    # first_book = data[0]
    # print(first_book)
    # # 取到物件的title屬性
    # print(first_book.title)
    # # 取到物件的press屬性
    # print(first_book.press)
    # # 取到和我這本書關聯的出版社的名字
    # print(first_book.press.name)
    # # 取到和我這本書關聯的出版社id
    # print(first_book.press_id)
    # # 連表查詢到出版社id
    # print(first_book.press.id)
    # print('-' * 120)
    # 2. 在頁面上展示出來
    # 3. 返回完整的HTML頁面
    return render(request, 'book_list.html', {'data': data})


# 新增書籍的處理函式
def add_book(request):
    if request.method == 'POST':
        # 1. 取到使用者填寫的資料
        book_title = request.POST.get('book_title')
        press_id = request.POST.get('press_id')
        # 2. 建立新的資料記錄
        # 基於外來鍵物件的建立
        # press_obj = Press.objects.get(id=press_id)
        # Book.objects.create(title=book_title, press=press_obj)# 這裡注意是press=
        # 基於外來鍵id值的建立
        Book.objects.create(title=book_title, press_id=press_id)# 這裡注意是press_id=
        # 3. 跳轉到書籍列表頁
        return redirect('/book_list/')
    # 1. 返回一個頁面,讓使用者填寫書籍資訊
    # 因為書籍資訊需要關聯出版社
    # 所以 在新增書籍的頁面要把已經存在的出版社展示出來,讓使用者選擇
    press_data = Press.objects.all()
    return render(request, 'add_book.html', {'press_list': press_data})


# 刪除書籍處理函式
def delete_book(request):
    # 1. 從URL中取到要刪除的書籍的id值
    delete_book_id = request.GET.get('id')
    # 2. 根據id值去資料庫找到對應的資料,刪除掉
    Book.objects.filter(id=delete_book_id).delete()
    # 3. 跳轉到書籍列表頁面
    # redirect實際做的事兒:
    # 給瀏覽器返回一個特殊的響應(命令)
    # 這個特殊的命令就是讓瀏覽器再發一次請求,訪問我指定的URL
    return render(request, 'delete_success.html')
    # return redirect('/book_list/')


# 編輯書籍處理函式
def edit_book(request):
    # 1. 從URL中取到要編輯的書籍的id值
    edit_book_id = request.GET.get('id')
    # 2. 根據id值找到要編輯的書籍物件
    edit_book_obj = Book.objects.get(id=edit_book_id)

    if request.method == 'POST':
        # 1. 取到使用者修改後的書籍名稱和出版社資訊
        new_title = request.POST.get('book_title')
        new_press_id = request.POST.get('press_id')
        # 2. 修改書籍相應資訊
        edit_book_obj.title = new_title
        edit_book_obj.press_id = new_press_id
        # 3. 儲存到資料庫
        edit_book_obj.save()
        # 4. 跳轉到書籍列表頁
        return redirect('/book_list/')

    # 2.2 把所有的出版社查詢出來
    press_data = Press.objects.all()
    # 3. 在頁面顯示出當前書籍的資訊,等待被編輯
    return render(
        request,
        'edit_book.html',
        {'book_obj': edit_book_obj, 'press_list': press_data}
    )
View Code

templates:

1.book_list.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>書籍列表頁</title>
</head>
<body>

<a href="/add_book/">新增書籍</a>

<table border="1">
    <thead>
    <tr>
        <th>序號</th>
        <th>書id</th>
        <th>書名稱</th>
        <th>出版社</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
        {% for book in data %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ book.id }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.press.name }}</td>
                <td>
                    <a href="/delete_book/?id={{ book.id }}">刪除</a>
                    <a href="/edit_book/?id={{ book.id }}">編輯</a>
                </td>
            </tr>
        {% endfor %}
    </tbody>
</table>
</body>
</html>
View Code

2.add_book.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>新增書籍</title>
</head>
<body>

<h1>新增書籍</h1>
<form action="/add_book/" method="post">
    <input type="text" name="book_title">
    <select name="press_id">
        {% for press in press_list %}
            <option value="{{ press.id }}">{{ press.name }}</option>
        {% endfor %}
    </select>
    <input type="submit">
</form>
</body>
</html>
View Code

3.edit_book.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>編輯書籍</title>
</head>
<body>
<h1>編輯書籍</h1>
<form action="" method="post">
    <input type="text" name="book_title" value="{{ book_obj.title }}">
    <select name="press_id" >
        {% for press in press_list %}
            {% if book_obj.press == press %}
                 <option selected value="{{ press.id }}">{{ press.name }}</option>
            {% else %}
                <option value="{{ press.id }}">{{ press.name }}</option>
            {% endif %}
        {% endfor %}
    </select>
    <input type="submit">
</form>

</body>
</html>
View Code

總結:

書籍的增刪改查
		1. 查詢
			1. book_obj.press              --> ORM層面封裝的,返回的是和我這本書關聯的出版社物件
			2. book_obj.press_id           --> 資料庫中真正存在的欄位,儲存的是和我關聯的出版社id值
		2. 增加
			1. 用select標籤把已經存在的出版社在頁面上展示出來
			   讓使用者去選擇
			   使用的是:模板語言的for迴圈
		3. 刪除
			1. 類似於上面出版社的操作
			
		4. 編輯
			1. 類似於於昨天的操作
			2. 用select標籤展示預設的出版社
				1. Django模板語言中的if判斷
					{% if 條件 %}
						...
					{% else %}
						...
					{% endif %}

  

三、作者增刪改查(多對多)

url

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [

    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),  # 編輯作者
]
View Code

models

from django.db import models



# 出版社表
class Press(models.Model):
    id = models.AutoField(primary_key=True)  # id主鍵
    name = models.CharField(max_length=32)  # 出版社名稱

    def __str__(self):
        return '<這是一個出版社物件,它的名字是:{}>'.format(self.name)


# 書
class Book(models.Model):
    id = models.AutoField(primary_key=True)  # 自增id主鍵
    title = models.CharField(max_length=30)  # 書名
    price = models.IntegerField()  # 價格
    # Django 1.11 預設就是級聯刪除, Django 2.0之後必須指定on_delete
    # to=關聯的表名
    press = models.ForeignKey(to='Press', on_delete=models.CASCADE)


# 作者
class Author(models.Model):
    id = models.AutoField(primary_key=True)  # 自增id主鍵
    name = models.CharField(max_length=32)  # 作者名字
    books = models.ManyToManyField(to='Book')  # 只是ORM層面建立的一個多對多關係,不是作者表的一個欄位

    def __str__(self):
        return self.name
View Code

views

from django.shortcuts import render, HttpResponse, redirect
from app01.models import User, Press, Book, Author

def author_list(request):
    # 1. 去資料庫查詢到所有的作者
    author_data = Author.objects.all()
    for author in author_data:
        print(author)
        # 取到每個作者出版的書籍
        # print(author.books)  # 是一個ORM提供的橋樑(工具),幫我找對應關係
        print(author.books.all())
    # 2. 在頁面上展示出來
    return render(request, 'author_list.html', {'author_list': author_data})


# 新增作者
def add_author(request):
    if request.method == 'POST':
        # 1. 取到使用者填寫的資訊
        new_author_name = request.POST.get('author_name')
        # book_ids = request.POST.get('books')  # -->這個只能取到一個值
        book_ids = request.POST.getlist('books')
        # print(new_author_name)
        # print(book_ids)
        print(request.POST.getlist('hobby'))
        print('-' * 120)
        # 2. 新增到資料庫
        # 2.1 建立新的作者
        author_obj = Author.objects.create(name=new_author_name)
        # 2.2 建立新作者和書的對應關係
        author_obj.books.add(*book_ids)  # 引數是一個一個單獨的書籍id值
        # author_obj.books.set(book_ids)  # 引數是書籍id值的列表
        # 3. 跳轉到作者列表頁面
        return redirect('/author_list/')
    # 1. 返回一個頁面給使用者,讓使用者填寫作者資訊
    # 2. 獲取所有的書籍資訊
    book_data = Book.objects.all()
    return render(request, 'add_author.html', {'book_list': book_data})


# 刪除作者
def delete_author(request):
    # 1. 取到要刪除的作者的id值
    delete_author_id = request.GET.get('kangchen')
    age = request.GET.get('age')
    print(delete_author_id)
    print(age)
    # 2. 同過id找到資料,並刪除
    Author.objects.filter(id=delete_author_id).delete()
    # 3. 讓使用者再訪問作者列表頁面
    return redirect('/author_list/')


# 編輯作者
def edit_author(request):
    # 1. 取到要編輯的作者的id值
    edit_author_id = request.GET.get('id')
    # 2. 找到要編輯的作者物件
    edit_author_obj = Author.objects.get(id=edit_author_id)

    if request.method == 'POST':
        # 3. 拿到編輯之後的資料
        new_author_name = request.POST.get('author_name')
        new_book_ids = request.POST.getlist('book_ids')
        # 4. 去資料庫修改
        # 4.1 修改作者表
        edit_author_obj.name = new_author_name
        edit_author_obj.save() # 修改好的作者物件提交到資料庫
        # 4.2 修改作者和書的關係表
        edit_author_obj.books.set(new_book_ids)
        # 5. 跳轉到作者列表頁面
        return redirect('/author_list/')

    # 2.2 找到所有的書籍物件
    book_data = Book.objects.all()
    # 3. 返回一個頁面
    return render(request, 'edit_author.html', {'author': edit_author_obj, 'book_list': book_data})
View Code

templates:

1.author_list.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>作者列表</title>
</head>
<body>

<a href="/add_author/">新增作者</a>
<table border="1">
    <thead>
    <tr>
        <th>序號</th>
        <th>作者id</th>
        <th>作者姓名</th>
        <th>作者作品</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for author in author_list %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ author.id }}</td>
            <td>{{ author.name }}</td>
            <td style="text-align: center">
                {% for book in author.books.all %}
                    {% if forloop.last %}
                        《{{ book.title }}》
                    {% else %}
                        《{{ book.title }}》,
                    {% endif %}
                {% empty %}
                    暫無作品
                {% endfor %}
            </td>
        <td>
            <a href="/delete_author/?kangchen={{ author.id }}&age=22">刪除</a>
            <a href="/edit_author/?id={{ author.id }}">編輯</a>
        </td>
        </tr>
    {% endfor %}
    </tbody>
</table>
</body>
</html>
View Code

2.add_author.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>新增作者</title>
</head>
<body>
<h1>新增作者</h1>

<form action="" method="post">
    <input type="text" name="author_name">
    <select name="books" multiple="multiple">
        {% for book in book_list %}
            <option value="{{ book.id }}">{{ book.title }}</option>
        {% endfor %}
    </select>

</form>

</body>
</html>
View Code

3.edit_author.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-Type" charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>編輯作者</title>
</head>
<body>

<h1>編輯作者</h1>
<form action="" method="post">
    <input type="text" name="author_name" value="{{ author.name }}">

    <select name="book_ids" multiple>
        {% for book in book_list %}
            如果 這本書 在 我這個作者關聯的書籍列表裡
            {% if book in author.books.all %}
                <option selected value="{{ book.id }}">{{ book.title }}</option>
            {% else %}
                <option value="{{ book.id }}">{{ book.title }}</option>
            {% endif %}
        {% endfor %}
    </select>
    <input type="submit">

</form>

</body>
</html>
View Code

總結:

	1. 多對多關係	
		作者   <-->  書籍
		1. 表結構設計
			1. SQL版
				-- 建立作者表
				create table author(
					id int primary key auto_increment,
					name varchar(32) not null
				);
				
				-- 建立作者和書的關係表
				create table author2book(
					id int primary key auto_increment,
					author_id int not null,
					book_id int not null,
					constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade,
					constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade
				);

			2. ORM版
				1. 第一版:
					自己建立第三張表
				2. 第二版
					讓ORM幫我們建立第三張表
					models.ManyToManyField()
				3. 第三版
					待補充...(ORM進階操作的時候)			
	2. 作者的增刪改查
		1. 查詢
			author_obj.books        --> 得到的只是一個關聯關係,並不能拿到資料
			author_obj.books.all()  --> 得到和我這個作者關聯的所有書籍物件列表
		2. 新增
			1. add()
			
		3. 刪除
		
		4. 編輯
			1. 模板語言中
				{% if book in author.books.all %}
			2. ORM編輯多對多
				1. 不能直接操作第三張關係表
				2. 藉助ORM給提供的方法
					1. all()
					2. add(id1,id2)
					3. set([id1, id2])
					4. clear()
	3. Django模板語言
		1. for迴圈
			1. forloop.last
				{% if forloop.last %}
					...
			2. empty
				{% for i in x %}
					...
				{% empty %}
					...
				{% endfor %}