第六章 Django实例

1.出版社管理

1.1 展示

1. 创建数据库

#打开cmd窗口,在 命令行,mysql中
create database dj_bookmanager

2. settings.py

  1. BASE_DIR:项目根目录

  2. debug = True(开发) / False(上线)

  3. INSTALL_APPS:注册app

  4. MIDDLEWARW:注释掉csrf校验

  5. TEMPLATES:模版文件目录

  6. DATABASES:配置mysql数据库(6)

  7. STATICFILES_DIRS:配置静态文件

3. models.py

  • 在__init.py中导入pymysql模块,替换默认链接方式

  • 并创建model类,并指定约束

    1. models.AutoField(primary_key = True) #自增并指定主键

    2. models.CharField(max_length=32, unqiue/default=xxx)

    3. models.IntegerField(default=0)

from django.db import models

class Publisher(models.Model):
  pid = models.AutoField(primary_key = True)
  name = models.CharField(max_length=32, unique=True)
  # 后续添加,需要指定默认值
  addr = models.CharField(max_length=32, default=‘xxx‘)
  # 或者更改迁移文件

4. 迁移数据库

python manage.py makemigrations
python manage.py migrate
# 插入数据

5. urls.py

from django.conf.urls import url
from django.contrib import admin
# 导入视图模块
from app1 import views
# 添加调用关系
urlpatterns = [
    url(r‘^admin/‘, admin.site.urls),
    url(r‘login‘, views.publisher_list),
]

6. views.py

from django.shortcuts import render, HttpResponse, redirect
def publisher_list(request):
  # 业务逻辑
    all_pubulisher = models.Pbulisher.objects.all().order_by(pk)
    return render(request, ‘publisher_list.html‘, {‘all_pubulisher‘:all_pubulisher})

7. xxx.html

  1. 这里使用的是django的渲染语法(在创建app也可以指定jinja2)

  2. {{变量}}{% for 循环%}{%endfor%}(需要闭合)

  3. 如果没有参数传入时,html中的{{变量}}在页面中不显示

{# for循环中有 forloop.counter 自动记录循环次数 #}
{% for publisher in all_publisher %}
    <tr>
    <td>{{forloop.counter}}</td>
    <td>{{publisher.pid/pk}}</td>
    <td>{{publisher.name}}</td>
    </tr>
{% endfor %}
{# if条件判断 #}
{% if 条件判断 %}
{% else %} / {% elif %}
{% endif %}

1.2 新增

  • models.类名.objects.create(字段=值)

# orm插入数据
obj = models.Publisher.objects.create(name=publisher_name)
# publisher object
print(obj)
  • 实例化方式
obj = models.Publisher(name=publisher_name)
obj.save()   # 保存到数据库中
# obj打印结果:Publisher obj
print(obj)

1.3 删除

  • obj.delete(),obj_list.delete()

  • 对像和对象列表都有delete方法

pk = request.GET.get(‘id‘)
obj_list = models.Publisher.objects.filter(pk=pk)
# 删除对象
if not obj_list:
  return HttpResponse(‘删除数据不存在‘)
obj_list.delete()

1.4 编辑

  • obj.字段=值

  • obj.save() 更新数据到数据库

# 从url中获取的参数,不是get请求的数据
pk = request.GET.get(‘id‘)
obj_list = models.Publiser.objects.filter(pk=pk)
if not obj_list:
  return HttpResponse(‘编辑数据不存在‘)

obj = obj_list[0]
# 内存中修改
obj.name = publisher_name
# 内存中数据,提交到数据库
obj.save()

2. 书籍管理

2.1 创建表结构

1. book表

  • name、作者、出版社、出版时间

class Book(models.Model):
  title = models.CharField(max_length=32)
  pub_id = models.ForeignKey(to=Publisher,on_delete=models.SET(字段))
  # on_delete=models.CASCADE(默认)
  # on_delete=models.SET(‘具体值’)
  # on_delete=models.SET_DEFAULT, defalut=‘xxx‘
  # on_delete=models.SET_NULL
    # on_delete参数在django2.0之后必填
  # 通过反射获取, on_delete默认级联删除
  pub = models.ForeignKey(‘Publisher‘, on_delete=models.SET_NULL)

2.创建book数据库

3. 数据库迁移

python manage.py makemigrations
python manage.py migrate
# 外键名django自动加 _id
# django.migrations也会在数据库中创建

2.2 查询

  • models.py

  • models中的pub是被关联类的对象

  • django会自动生成 pub_id

for book in all_Book.objects.all():
    # book类中属性
    print(book.pk)
    print(book.title)
    print(book.pub_id)
    print(book.pub, type(book.pub))
    # publisher中属性
    # print(book.pub_id)只需要出版社id,建议使用
    print(book.pub.pk)
    print(book.name)
for+table,自动补全,pycharm提供
# __str__方法
print(book.pub)

2.3 展示

def list_book(request):
    all_books = models.Book.objects.all()
    return render(request, ‘list_book.html‘, {‘all_books‘: all_books})

2.4 新增

  • views.py

def add_book(request):
    error = ‘‘
    if request.method == ‘POST‘:
        title = request.POST.get(‘book_name‘)
        pk = request.POST.get(‘id‘)
        print(title, pk)
        # 可以使用多个字段进行查找
        book_set = models.Book.objects.filter(title=title, pub_id=pk)
        if book_set:
            error = ‘书籍已存在‘
        if not title: error = ‘请输入书名‘
        if not error:
            models.Book.objects.create(title=title, pub_id=pk)
            return redirect(‘/list_book/‘)
    all_publisher = models.Publisher.objects.all()
    return render(request, ‘add_book.html‘, {‘all_publisher‘: all_publisher, ‘error‘: error})

2.5 删除

  • 数据库查询到的对象 或 query set 都可以使用delete方法直接删除数据

def del_book(request):
    if request.method == ‘GET‘:
        pk = request.GET.get(‘id‘)
        models.Book.objects.filter(id=pk).delete()
        return redirect(‘/list_book/‘)

2.6 修改

  • 通过 GET 、 POST 获取的数据一般为 字符串类型

  • 获取的 pub_id 是 str 类型,注意和数据库中字段类型一样

def edit_book(request):
    error = ‘‘
    pk = request.GET.get(‘id‘)
    book = models.Book.objects.get(pk=pk)
    if request.method == ‘POST‘:
        title = request.POST.get(‘book_name‘)
        # 获取的 pub_id 是 str 类型,注意和数据库中字段类型一样
        pub_id = request.POST.get(‘id‘)
        print(type(title), type(book.title), type(pub_id), type(book.pub_id))
        # 判断 书名+出版社 是否被修改
        if book.title == title and book.pub_id == int(pub_id):
            error = ‘未做任何修改‘
        if not title: error = ‘请输入书名‘
        # 判断 书名+出版社 是否唯一
        if models.Book.objects.filter(title=title, pub_id=pub_id):
            error = ‘该书籍已存在‘
        if not error:
            book.title = title
            book.pub_id = pub_id
            book.save()
            return redirect(‘/list_book/‘)
    all_publisher = models.Publisher.objects.all().order_by(‘pid‘)
    return render(request, ‘edit_book.html‘, {‘book‘: book, ‘all_publisher‘: all_publisher, ‘error‘: error})