Django课堂笔记001

Django课堂笔记001

第1次-搭建环境

进入workspace_python目录,创建Django项目

django-admin startproject chapter04

进入chapter04目录,创建应用

python manage.py startapp booklist

第2次-路由系统

第3次-模型

定义模型

from django.db import models


# 定义books应用书籍模型类
class BookInfo(models.Model):
    name = models.CharField(max_length=20, verbose_name="名称")
    pub_date = models.DateField(verbose_name="发布日期")
    readCount = models.IntegerField(default=0, verbose_name="阅读量")
    commentCount = models.IntegerField(default=0, verbose_name="评论量")
    is_delete = models.BooleanField(default=False, verbose_name="逻辑删除")

    #  将查询结果以字符串形式显示
    def __str__(self):
        return self.name


class Demo(models.Model):
    car_name = models.CharField(max_length=32, verbose_name='车牌号')
    park_name = models.CharField(max_length=32)
    come_date = models.CharField(max_length=32)
    leave_date = models.CharField(max_length=32)
    time = models.CharField(max_length=32)

    #  将查询结果以字符串形式显示
    def __str__(self):
        return self.name

总结:

  1. Django中的模型用Python类的形式来定义
  2. 这个模型类定义在应用的models.py中,并且要继承models.Model类
  3. 非抽象的模型对应一张数据表

生成迁移文件

python manage.py makemigrations

输出内容

PS D:\workspace_python\chapter03> python manage.py makemigrations
Migrations for 'books':
  books\migrations\0001_initial.py
    - Create model BookInfo
    - Create model Demo

会根据models.py文件生成一个中间文件,并保存在migrations目录中,如0001_initial.py

执行迁移文件

python manage.py migrate

插入数据

在对应的views.py文件中定义如下视图函数

def db_create(request):
    models.Demo.objects.create(car_name='豫A12345', come_date='进来时间为3月2日', leave_date='离开日期为3月4日', time='1')
    return HttpResponse("insert OK")

urls.py中添加

path('dbinsert/', views.db_create)

总结:

第4次-模板

准备环境

进入workspace_python目录,创建Django项目

django-admin startproject chapter04

进入chapter04目录,创建应用

python manage.py startapp booklist

将应用添加到settings.py的INSTALLEDAPP中

'booklist'

在booklist目录下views.py文件中创建一个视图函数test

from django.http import HttpResponse


def test(request):
    return HttpResponse("test")

完成url与视频函数的映射

在booklist/urls.py中

from django.urls import path

from booklist import views

urlpatterns = [path('test/', views.test)]

在项目的urls.py的urlpatterns数组中添加如下

path('booklist/', include('booklist.urls'))

运行项目

python manage.py runserver

浏览器中输入url

http://127.0.0.1:8000/booklist/test/

变量的用法

第一步:定义视图函数

def checkfirst(request):
    strlen = 'python'
    num = 3
    return render(request, 'test.html', {
    
    'strlen': strlen, 'num': num})

在booklist下urls.py中配置子路由

from django.urls import path

from booklist import views

urlpatterns = [
    path('test/', views.test),
    path('checkfirst/', views.checkfirst)
]

第二步:项目目录下创建templates文件夹,在文件夹里创建test.html文件

<body>
<h1>内置过滤器1</h1>
    <p>使用前{
   
   { strlen }}</p>
    <p>使用后{
   
   { strlen|capfirst}}</p>
</body>

第四步:配置模板路径

在setting.py中,在TEMPLATES里添加路径

'DIRS': ['templates'],

第五步,启动服务器测试

python manage.py runserver

add过滤器的用法

test.html文件里添加,

<h1>一个值使用add过滤器</h1>
    <p>使用前:{
   
   { num }}</p>
    <p>使用后:{
   
   { num|add:4}}</p>

官方内置过滤器

https://docs.djangoproject.com/zh-hans/4.1/ref/templates/builtins/#filters

标签的使用

第一步,views.py文件里创建视图

class GF(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age 

def chacktag(request):
    data = {
    
    
        'name': '张三',
        'age': 25,
        'likes': ['足球', '篮球', '排球'],
        'teacher': {
    
    
            'name': '李四',
            'age': 50,
            'sex': '男'
        },
        'gf': GF(name='王五', age=24)
    }
    return render(request, 'taguse.html', data)

第二步:在booklist应用下urls.py中配置子路由

path('taguse/',views.chacktag)

第三步,新建标签,taguse.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>标签的使用</h1>
{% if age < 18 %}
    未成年
    {% elif age == 18  %}
    刚成年
    {% else %}
    已成年
{% endif %}
<h2>喜欢的球类</h2>
{% for like in likes %}
    {
   
   { like }}
{% endfor %}
<h2>老师信息</h2>
{% for t in teacher.values %}
    {
   
   { t }}
{% endfor %}
<h2>对象信息</h2>
姓名:{
   
   { gf.name }},年龄:{
   
   { gf.age }}
</body>
</html>

第四步,访问服务器,python manage.py runserver
taguse/

自定义过滤器

第一步在booklist应用下建立templatetags目录

​ 这个目录必须是templatetags,不是这个名字会找不到定义的过滤器

第二步,在templatetags中创建filters.py,用于自定义过滤器和标签

from django import template

register = template.Library()

# 定义加过滤器
def examp(value, arg):
    return value + arg

# 注册过滤器
register.filter('examp', examp)

第三步,使用自定义的过滤器

在taguse.html中使用

{
    
    % load filters %}

先要使用load标签加载自定义标签

<p>年龄:{
   
   { age |examp:100 }}</p>

**注意:**如果有报异常,需要重启一下服务器

自定义标签

在上面的filters.py中增加自定义标签

# 自定义标签并注册
@register.simple_tag()
def current_time(format_str):
    return datetime.now().strftime(format_str)

使用自定义标签

在taguse.html中增加下面代码

<h1>自定义标签</h1>
<p>日期时间:{% current_time '%b %d %Y %H:%M:%S' %}</p>
<p>now标签{% now 'jS F Y H:i' %}</p>

**注解:**标签的含义

https://m.w3schools.cn/django/ref_tags_now.asp

模板的继承

首先,templates下建立base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>{% block title %}页面标题{% endblock %}</title>
</head>
<body>
{% block header %}
    <h1>标题</h1>
{% endblock header %}
{% block main %}
    <h2>页面内容</h2>
{% endblock %}
<br><br><br>
{% block footer %}
    <div class="footer no-mp">
        <div class="foot_link">
            <a href="#">关于我们</a>
            <span> | </span>
            <a href="#">联系我们</a>
            <span> | </span>
            <a href="#">招聘人才</a>
            <span> | </span>
            <a href="#">友情链接</a>
        </div>
		<p>CopyRight © 2019 北京小鱼商业股份有限公司 All Rights Reserved</p>
		<p>电话:010-****888    京ICP备*******8号</p>
    </div>
{% endblock %}
</body>
</html>

然后,创建视图,views.py

def show_base_page(request):
    return render(request, 'base.html')

创建子路由 path(‘base/’, views.show_base_page),
此时,浏览器访问base/,即可查看效果

然后定义一个继承该模板的子模版lists.html

{% extends 'base.html' %}
{% block title %}
    列表页面
{% endblock %}
{% block header %}
    <h1>书单</h1>
{% endblock header %}
{% block main %}
    <a href="#">1.《鲁迅作品全集》</a><br>
    <a href="#">2.《秋雨散文集》</a><br>
    <a href="#">3.《黑暗森林》</a><br>
    <a href="#">4.《月亮与六便士》</a><br>
{% endblock main %}
<br><br><br>

创建视图,

def show_page(request):
    return render(request, 'lists.html')

添加路由

path('lists/', views.show_page),

此时,浏览器访问booklist/lists/,即可查看效果

第5次-视图

准备环境

创建django项目

django-admin startproject chapter05

创建goods应用

cd chapter05
python manage.py startapp goods

配置应用

在setting.py中,已安装app那里添加应用goods

配置主路由

chapter05的urls.py中

 path('chapter05/', include('goods.urls')),

测试路由参数传递

1、定义视图函数

from django.http import HttpResponse
from django.shortcuts import render


# Create your views here.
# 从url中接收参数id
def test(request, id):
    s = '从url中接收来的str数据为:' + id;
    print(s)
    return HttpResponse(s)

2、在goods应用的urls.py中配置路由

from django.urls import path

from goods import views

urlpatterns = [
    path('test/<str:id>/', views.test),
]

3、测试

http://127.0.0.1:8000/chapter05/test/1

展示商品

本质就是读取数据库中存取的商品数据,并在HTML中显示。

创建模型

goods/modles.py

from django.db import models


class Goods(models.Model):
    """商品SKU"""
    # 可以利用null和blank属性使部分字段留空
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    name = models.CharField(max_length=50, verbose_name='名字')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
    stock = models.IntegerField(default=0, verbose_name='库存')
    sales = models.IntegerField(default=0, verbose_name='销量')

    class Meta:
        db_table = 'tb_goods'
        verbose_name = '商品'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.id, self.name)

生成迁移文件并执行迁移

python manage.py makemigrations
python manage.py migrate

插入数据

利用数据文件goods.sql插入商品数据

INSERT INTO tb_goods (create_time, update_time, name, price, stock, sales) VALUES
('2019-09-11 17:28:21.804713', '2019-09-25 11:09:04.532866', 'Apple MacBook Pro 13.3英寸笔记本 银色', 11388, 5, 5),
('2019-09-12 06:53:54.575306', '2019-09-23 11:44:03.825103', 'Apple MacBook Pro 13.3英寸笔记本 深灰色', 11398, 0, 1),
('2019-09-14 02:14:04.599169', '2019-09-20 02:28:13.579856', 'Apple iPhone 11 Pro 256GB 香芋紫', 6499, 6, 4),
('2019-09-14 02:20:33.355996', '2019-09-14 17:27:12.736139', 'Apple iPhone 11 Plus 256GB 金色', 7988, 8, 2),
('2019-09-14 02:45:23.341909', '2019-09-14 17:27:17.181609', 'Apple iPhone 11 Plus 64GB 深空灰色', 6688, 10, 0),
('2019-09-14 02:49:40.912682', '2019-09-25 11:09:35.936530', 'Apple iPhone 11 Plus 256GB 深空灰色', 7988, 0, 5),
('2019-09-14 02:55:11.172604', '2019-09-14 17:27:28.772353', 'Apple iPhone 11 Plus 64GB 银色', 6688, 3, 0),
('2019-09-14 02:56:17.331169', '2019-09-14 17:27:34.536772', 'Apple iPhone 11 Plus 256GB 银色', 7988, 9, 1),
('2019-09-14 03:09:00.909709', '2019-09-14 17:27:40.624770', '华为 HUAWEI Pro 30 6GB+64GB 钻雕金', 3388, 4, 0),
( '2019-09-14 03:13:40.226704', '2019-09-25 11:06:55.087206', '华为 HUAWEI Pro 30 6GB+128GB 钻雕金', 3788, 3, 0),
( '2019-09-14 03:16:27.620102', '2019-09-25 10:56:51.267674', '华为 HUAWEI Pro 30 6GB+128GB 钻雕蓝', 3788, 5, 0),
( '2019-09-14 03:17:25.671905', '2019-09-14 17:28:06.649098', '华为 HUAWEI Pro 30 6GB+64GB 钻雕蓝', 3388, 5, 0),
( '2019-09-14 03:18:04.588296', '2019-09-14 17:28:23.886231', '华为 HUAWEI Pro 30 6GB+64GB 玫瑰金', 3388, 5, 0),
( '2019-09-14 03:19:03.691772', '2019-09-25 11:10:51.316291', '华为 HUAWEI Pro 30 6GB+128GB 玫瑰金', 3788, 0, 4),
( '2019-09-20 02:27:04.955931', '2019-09-20 02:27:04.956931', 'Apple iPhone 11 Pro 256GB 香芋紫', 6499, 6, 3);

配置模板

项目底下创建templates文件夹,

在settings.py中配置DIRS

在文件夹里创建goods.html文件

<html lang="en">
<head>
    <title>商品列表</title>
</head>
<body>
<div>
    <table id="myTable" cellpadding="1" cellspacing="0" border="1"
           style="width:100%;max-width: 100%;margin-bottom: 20px ">
        <caption align="top" style="font-size: 26px">商品列表</caption>
        <thead>
        <tr>
            <th>编号</th>
            <th>商品</th>
            <th>价格</th>
            <th>库存</th>
            <th>销量</th>
            <th>管理</th>
        </tr>
        </thead>
        <tbody>
        {% for row in goods %}
            <tr align="center">
                <td>{
   
   { forloop.counter }}</td>
                <td>{
   
   { row.name }}</td>
                <td>{
   
   { row.price }}</td>
                <td>{
   
   { row.stock }}</td>
                <td>{
   
   { row.sales }}</td>
                <td>
                    <a href="/chapter05/delete/{
     
     { forloop.counter }}/">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
</body>
</html>

定义视图函数

在应用的views.py文件中,定义get_goods()实现展示商品的功能。

from django import http
from django.template import loader

from goods.models import Goods


def test(request, id):
    s = '从url中接收来的str数据为:' + id;
    print(s)
    return http.HttpResponse(s)


def get_goods(request):
    """展示商品"""
    goods = Goods.objects.all()  # 获取所有商品
    context = {
    
    
        'goods': goods,
    }
    
    template = loader.get_template('goods.html')
    response = template.render(context, request)
    return http.HttpResponse(response)

配置子路由

goods应用urls.py中添加

# 展示商品信息
path('goods/', views.get_goods),

测试

http://127.0.0.1:8000/chapter05/goods/

删除商品

本质就是获取用户要删除的商品id,在数据库中删除该id对应的记录,再重定向到商品列表页面,展示更新后的商品数据。

def del_goods(request, gid):
    """删除指定商品"""
    print('---------即将删除gid为: ' + gid + '商品----------')

    good = Goods.objects.get(id=gid)
    good.delete()
    return http.HttpResponseRedirect('/chapter05/goods/')  # 重定向到首页

配置子路由

path('delete/<str:gid>/', views.del_goods),

新增商品

1、在html中新增表单模块

<div>
    {# 表单一:添加 #}
    <form method="post" action="/chapter05/add_goods/" cellpadding="1" cellspacing="0"
          border="1">
        {% csrf_token %}
        <input type="submit" value="添加">
        商品:<input type="text" name="good_name">
        价格:<input type="text" name="good_price">
        库存:<input type="text" name="good_stock">
        销量:<input type="text" name="good_sales">
    </form>
</div>

2、增加对应的视图函数

def add_goods(request):
    """添加商品"""
    if request.method == 'POST':
        good = Goods()
        try:
            good.name = request.POST.get('good_name')
            good.price = request.POST.get('good_price')
            good.stock = request.POST.get('good_stock')
            good.sales = request.POST.get('good_sales')
            good.save()
            return redirect('/chapter05/goods/')  # 快捷方式
        except Exception as e:
            return http.HttpResponseForbidden('数据错误')

3、配置子路由

path('add_goods/', views.add_goods)

4、测试

点击”添加“之后,注意列表的变化。

更新商品

1、在html中新增表单

<div>
    {# 表单二:修改 #}
    <form method="post" action="/chapter05/update/" cellpadding="1" cellspacing="0"
          border="1">
        {% csrf_token %}
        <input type="submit" value="修改">
        序号:<input type="text" name="good_num">
        商品:<input type="text" name="good_name">
        价格:<input type="text" name="good_price">
        库存:<input type="text" name="good_stock">
        销量:<input type="text" name="good_sales">
    </form>
</div>

2、新增对应的视图函数

def update_goods(request):
    """编辑商品"""
    print(request.method)
    if request.method == 'POST':
        goods = Goods.objects.all()
        count = goods.count()
        try:
            num = request.POST.get('good_num')
            for i in range(1, count + 1):
                if i == int(num):
                    good = goods[i - 1]
                    good.name = request.POST.get('good_name')
                    good.price = request.POST.get('good_price')
                    good.stock = request.POST.get('good_stock')
                    good.sales = request.POST.get('good_sales')
                    good.save()
                    break
        except Exception as e:
            return http.HttpResponseForbidden('编辑失败')

    return redirect('/chapter05/goods/')

3、配置子路由

path('update/', views.update_goods)

4、测试

修改之后,注意对应id一行数据的变化。

用类视图改造

以类的形式定义视图

class GoodsView(View):
    def get(self, request):
        return get_goods(request)

    def post(self, request):
        return add_goods(request)

配置路由

path('getorpost/', GoodsView.as_view())

注意这里的GoodsView.as_view(),它会根据请求的实际方式来决定调用get方法还是post方法

利用增加操作来修改为

<div>
    {# 表单一:添加 #}
{#    <form method="post" action="/chapter05/add/" cellpadding="1" cellspacing="0"#}
{#          border="1">#}
    <form method="post" action="/chapter05/getorpost/" cellpadding="1" cellspacing="0"
              border="1">
        {% csrf_token %}
        <input type="submit" value="添加">
        商品:<input type="text" name="good_name">
        价格:<input type="text" name="good_price">
        库存:<input type="text" name="good_stock">
        销量:<input type="text" name="good_sales">
    </form>
</div>

测试

http://127.0.0.1:8000/chapter05/getorpost/

第6次-后台管理系统admin

准备环境

1、创建django项目,应用

django-admin startproject chapter06
python manage.py startapp goods

在settings.py中注册goods应用

2、创建模型

goods/modles.py

from django.db import models


class Goods(models.Model):
    """商品SKU"""
    # 可以利用null和blank属性使部分字段留空
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    name = models.CharField(max_length=50, verbose_name='名字')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
    stock = models.IntegerField(default=0, verbose_name='库存')
    sales = models.IntegerField(default=0, verbose_name='销量')

    class Meta:
        db_table = 'tb_goods'
        verbose_name = '商品'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.id, self.name)

2、数据库迁移

python manage.py makemigrations
python manage.py migrate

创建管理员账号

python manage.py createsuperuser
Username: admin
Email address: admin@163.com    #设置的邮箱为:[email protected]
Password:                      # 设置的密码为:12345678
Password (again):
Superuser created successfully.

设置系统语言

有以下两种方式

  1. 在settings.py文件中将配置项LANGUAGE_CODE的值设置为“zh-Hans”。
  2. 在settings.py文件中将配置项MIDDLEWARE中添加中间件’django.middleware.locale.LocaleMiddleware’

将模型注册到后台管理系统

有两种注册模型的方式

在goods/admin.py中

装饰器注册

from django.contrib import admin
@admin.register(Goods)
class GoodsAdmin(admin.ModelAdmin):
    pass

代码注册

from django.contrib import admin

from goods.models import Goods


class GoodsAdmin(admin.ModelAdmin):
    pass


admin.site.register(Goods, GoodsAdmin)

设置应用名中文显示

在goods应用的_init__.py文件中添加如下设置,表示加载goods/apps.py文件中的GoodsConfig的配置信息。

default_app_config = 'goods.apps.GoodsConfig'

然后在goods/apps.py文件的GoodsConfig类中使用verbose_name设置应用的名称

class GoodsConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'goods'
    verbose_name = '商品'

管理数据库

列表页选项

下面几个选项均在goods/admin.py中GoodsAdmin类中添加

list_display选项

用于控制页面展示的字段,选项的值可以是元组,也可以是列表。

list_display = ('id', 'create_time', 'update_time', 'name', 'price', 'stock', 'sales',)
list_display_links选项

以链接形式展示字段

list_display_links = ('id', 'name',)
list_filter选项
list_filter = ('stock',)
list_per_page选项
list_per_page = 10
list_editable选项

页面是否可直接编辑

list_editable = ('name',)

编辑页选项

fields选项

用于控制编辑页要展示的字段,它的值是元组类型。

fields = ('name', 'price', 'stock',)
fields-set选项

对可编辑字段进行分组,不可与fields选项同时使用

fieldsets = (
    ('基本信息', {
    
    'fields': ['name', 'stock', 'sales']}),
    ('价格信息', {
    
    'fields': ['price']})
)

重写后台模板

(1)创建目录,templates和static,并在templates下创建admin目录;
(2)在templates/admin创建base_site.html,base_site.html代码如下

{% extends "admin/base.html" %}
{% load static %}
{% block title %}{
   
   { title }} | {
   
   { site_title|default:_('Django site admin') }}
{% endblock %}
{% block branding %}
    <h1 id="site-name">
        <a href="{% url 'admin:index' %}">
            <!--  logo.png为网站logo图片-->
            <img src="{% static 'logo.png' %}" height="40px"/>
        </a>
    </h1>
{% endblock %}
{% block nav-global %}{% endblock %}

在settings.py中配置模板路径

'DIRS': ['templates'],

(3)在setting.py文件中配置目录

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

(4)把准备好的logo图片添加到static目录下边。
(5)运行看效果。

第7次-表单

准备环境

1、新建项目chapter07

django-admin startproject chapter07

2、新建应用goods

python manage.py startapp goods

3、在setting.py中,已安装app那里添加应用goods

4、项目底下创建templates文件夹,在文件夹里创建goods.html文件

在项目的setting.py文件中的BASE_DIR之后追加导包路径:

'DIRS': ['templates'],

goods.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>商品列表</title>
</head>
<body>
<div>
    <table id="myTable" cellpadding="1" cellspacing="0" border="1"
           style="width:100%;max-width: 100%;margin-bottom: 20px ">
        <caption align="top" style="font-size: 26px">商品列表</caption>
        <thead>
        <tr>
            <th>序号</th>
            <th>名字</th>
            <th>价格</th>
            <th>库存</th>
            <th>销量</th>
            <th>管理</th>
        </tr>
        </thead>
        <tbody>
        {% for row in goods %}
            <tr align="center">
                <td>{
   
   { forloop.counter }}</td>
                <td>{
   
   { row.name }}</td>
                <td>{
   
   { row.price }}</td>
                <td>{
   
   { row.stock }}</td>
                <td>{
   
   { row.sales }}</td>
                <td>
                    <a href="goods/{
     
     { row.id }}">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>
<div>
    {#  表单一:添加  #}
    <form method="post" action="/" cellpadding="1" cellspacing="0"
          border="1">
        {% csrf_token %}
        <input type="submit" value="添加">
        商品:<input type="text" name="good_name">
        价格:<input type="text" name="good_price">
        库存:<input type="text" name="good_stock">
        销量:<input type="text" name="good_sales">
    </form>
</div>
<div>
    {#                            表单二:修改                              #}
    <form method="post" action="goods/" cellpadding="1" cellspacing="0"
          border="1">
        {% csrf_token %}
        <input type="submit" value="修改">
        序号:<input type="text" name="good_num">
        商品:<input type="text" name="good_name">
        价格:<input type="text" name="good_price">
        库存:<input type="text" name="good_stock">
        销量:<input type="text" name="good_sales">
    </form>
</div>
</body>
</html>

5、在models里,实现商品管理需要用到商品模型类Goods

from django.db import models
class Goods(models.Model):
    """商品SKU"""
    # 可以利用null和blank属性使部分字段留空
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    name = models.CharField(max_length=50, verbose_name='名字')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
    stock = models.IntegerField(default=0, verbose_name='库存')
    sales = models.IntegerField(default=0, verbose_name='销量')

    class Meta:
        db_table = 'tb_goods'
        verbose_name = '商品'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.id, self.name)

6、生成迁移文件并执行迁移

python manage.py makemigrations
python manage.py migrate

7、在views.py文件里,展示商品和删除商品的逻辑。然后分别在类GoodView和UpdateDestoryGood中实现商品展示和删除的功能。views.py全部代码如下。

from django.shortcuts import render, redirect, reverse
from django.views import View
from django import http
from .models import Goods


# Create your views here.
class GoodView(View):
    """商品视图类"""

    def get(self, request):
        """展示商品"""
        goods = Goods.objects.all()
        context = {
    
    
            'goods': goods,
        }
        return render(request, 'goods.html', context)

    def post(self, request):
        """添加商品"""
        good = Goods()
        try:
            good.name = request.POST.get('good_name')
            good.price = request.POST.get('good_price')
            good.stock = request.POST.get('good_stock')
            good.sales = request.POST.get('good_sales')
            good.save()
            # return redirect('/')  # 快捷方式
            return redirect(reverse('goods:info'))
        except Exception as e:
            return http.HttpResponseForbidden('数据错误')


class UpdateDestoryGood(View):
    """编辑或删除商品"""

    def get(self, request, gid):
        """删除商品数据"""
        try:
            good = Goods.objects.get(id=gid)
            good.delete()
        except Exception as e:
            return http.HttpResponseForbidden('删除失败')
        return redirect(reverse('goods:info'))

    def post(self, request, gid=0):
        """编辑商品"""
        goods = Goods.objects.all()
        count = goods.count()
        try:
            num = request.POST.get('good_num')
            for i in range(1, count + 1):
                if i == int(num):
                    good = goods[i - 1]
                    good.name = request.POST.get('good_name')
                    good.price = request.POST.get('good_price')
                    good.stock = request.POST.get('good_stock')
                    good.sales = request.POST.get('good_sales')
                    good.save()
                    break
        except Exception as e:
            return http.HttpResponseForbidden('编辑失败')
        return redirect(reverse('goods:info'))

8、配置路由

(1)urls.py(保持根url不变)

from django.urls import path, include, re_path
re_path('^', include('goods.urls')),

(2)goods/urls.py

from django.urls import re_path
from . import views
app_name = 'goods'
urlpatterns = [
    # 展示商品数据、添加商品
    re_path(r'^$', views.GoodsView.as_view(), name='info'),
    # 修改删除商品
    re_path(r'^goods/(\d*)$', views.UpdateDestoryGood.as_view()),
]

基本概念补充

给URL命名

在path()函数或re_path()函数中使用参数name为URL命名,示例如下

urlpatterns = [
    re_path(r'^$', views.GoodView.as_view(), name='info'),
]

反向解析

概念:通过URL的名字,获取到对应的URL。

方式:reverse(‘info’),

命名空间

在Django中,多个应用可能包含同名的URL,为了避免反向解析时产生混淆,可以命名空间来区分不同的应用。

只需在应用的urls.py文件中定义app_name变量,便可指定当前应用的命名空间,格式为“app_name=URL名称

使用正则表达式匹配路由

语法格式

re_path(r'^goods/(\d*)$', views.UpdateDestoryGood.as_view())

类视图

假设来自同一URL的GET和POST请求,分别以函数视图和类视图来实现

函数视图的方式

from django.http import HttpResponse
def my_view(request):
	if request.method == 'GET':
		return HttpResponse('POST')
	elif request.method == 'POST':
		return HttpResponse('POST')

类视图的方式

from django.http import HttpResponse
from django.views import View
class MyView(View):
	def get(self,request):
		return HttpResponse('POST')
	def post(self,request):
		return HttpResponse('POST')

插入数据

利用数据文件goods.sql插入商品数据,

INSERT INTO tb_goods (create_time, update_time, name, price, stock, sales) VALUES
('2019-09-11 17:28:21.804713', '2019-09-25 11:09:04.532866', 'Apple MacBook Pro 13.3英寸笔记本 银色', 11388, 5, 5),
('2019-09-12 06:53:54.575306', '2019-09-23 11:44:03.825103', 'Apple MacBook Pro 13.3英寸笔记本 深灰色', 11398, 0, 1),
('2019-09-14 02:14:04.599169', '2019-09-20 02:28:13.579856', 'Apple iPhone 11 Pro 256GB 香芋紫', 6499, 6, 4),
('2019-09-14 02:20:33.355996', '2019-09-14 17:27:12.736139', 'Apple iPhone 11 Plus 256GB 金色', 7988, 8, 2),
('2019-09-14 02:45:23.341909', '2019-09-14 17:27:17.181609', 'Apple iPhone 11 Plus 64GB 深空灰色', 6688, 10, 0),
('2019-09-14 02:49:40.912682', '2019-09-25 11:09:35.936530', 'Apple iPhone 11 Plus 256GB 深空灰色', 7988, 0, 5),
('2019-09-14 02:55:11.172604', '2019-09-14 17:27:28.772353', 'Apple iPhone 11 Plus 64GB 银色', 6688, 3, 0),
('2019-09-14 02:56:17.331169', '2019-09-14 17:27:34.536772', 'Apple iPhone 11 Plus 256GB 银色', 7988, 9, 1),
('2019-09-14 03:09:00.909709', '2019-09-14 17:27:40.624770', '华为 HUAWEI Pro 30 6GB+64GB 钻雕金', 3388, 4, 0),
( '2019-09-14 03:13:40.226704', '2019-09-25 11:06:55.087206', '华为 HUAWEI Pro 30 6GB+128GB 钻雕金', 3788, 3, 0),
( '2019-09-14 03:16:27.620102', '2019-09-25 10:56:51.267674', '华为 HUAWEI Pro 30 6GB+128GB 钻雕蓝', 3788, 5, 0),
( '2019-09-14 03:17:25.671905', '2019-09-14 17:28:06.649098', '华为 HUAWEI Pro 30 6GB+64GB 钻雕蓝', 3388, 5, 0),
( '2019-09-14 03:18:04.588296', '2019-09-14 17:28:23.886231', '华为 HUAWEI Pro 30 6GB+64GB 玫瑰金', 3388, 5, 0),
( '2019-09-14 03:19:03.691772', '2019-09-25 11:10:51.316291', '华为 HUAWEI Pro 30 6GB+128GB 玫瑰金', 3788, 0, 4),
( '2019-09-20 02:27:04.955931', '2019-09-20 02:27:04.956931', 'Apple iPhone 11 Pro 256GB 香芋紫', 6499, 6, 3);

使用表单类

1、在goods应用中创建forms.py,在其中定义表单类,代码如下:

from django import forms
from django.forms import ModelForm
from django.forms import formset_factory
from . import models
from .models import Goods


class GoodForm(ModelForm):
    class Meta:
        model = Goods
        fields = ['name', 'price', 'sales', 'stock']

2、添加

<div>
    <form method="post" action="/">
        {% csrf_token %}
                <input type="submit" value="添加">
                {
   
   { form }}
    </form>
</div>

3、

<div>
    <form method="post" action="goods/" cellpadding="1" cellspacing="0" border="1">
        {% csrf_token %}
        <input type="submit" value="修改">
        序号: <input type="text" name="good_num">
        {
   
   { form }}
    </form>
</div>
from django import http
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View

from goods.form import GoodForm
from goods.models import Goods


class GoodsView(View):
    """商品视图类"""

    # 查询所有商品
    def get(self, request):
        # goods = Goods.objects.all()
        # context = {'goodsList': goods}
        # return render(request, 'goods.html', context)
        
    	# 使用表单
        goods = Goods.objects.all()
        form = GoodForm()
        context = {
    
    
            'goods': goods,
            'form': form,
        }
        return render(request, 'goods.html', context)

    def post(self, request):
        # 创建空的商品对象
        # print(request.POST)
        # goods = Goods()
        # goods.sales = request.POST.get("good_sales")
        # goods.name = request.POST.get("good_name")
        # goods.price = request.POST.get("good_price")
        # goods.stock = request.POST.get("good_stock")
        # goods.save()
        # print("反向解析:" + reverse('goods:info'))
        # return redirect('goods:info')

        # 使用表单
        good = Goods()
        # 使用已提交的数据实例化NameForm
        form = GoodForm(request.POST)
        # 判断表单是否已验证,获取已验证的数据
        if form.is_valid():
            good_data = form.cleaned_data
            good.name = good_data['name']
            good.price = good_data['price']
            good.stock = good_data['stock']
            good.sales = good_data['sales']
            try:
                good.save()
            except:
                return http.HttpResponseForbidden('数据错误')
        return redirect(reverse('goods:info'))


class UpdateDestoryGood(View):
    """删除和修改的视图类"""

    def get(self, request, gid):
        print('gid=' + gid)
        goods = Goods.objects.get(id=gid)
        goods.delete()
        return redirect('goods:info')

    def post(self, request, gid):
        # 使用模板
        # goods = Goods.objects.all()
        # count = goods.count()
        #
        # num = request.POST.get('good_num')  # 取到序号
        # for i in range(1, count + 1):
        #     if i == int(num):
        #         good = goods[i - 1]
        #         good.name = request.POST.get('good_name')
        #         good.price = request.POST.get('good_price')
        #         good.stock = request.POST.get('good_stock')
        #         good.sales = request.POST.get('good_sales')
        #         good.save()
        #
        # return redirect(reverse('goods:info'))

        # 使用表单
        goods = Goods.objects.all()
        count = goods.count()
        form = GoodForm(request.POST)
        good_num = request.POST.get('good_num')
        if form.is_valid():
            good_data = form.cleaned_data
            for i in range(1, count + 1):
                if i == int(good_num):
                    good = goods[i - 1]
                    good.name = good_data['name']
                    good.price = good_data['price']
                    good.stock = good_data['stock']
                    good.sales = good_data['sales']
                    try:
                        good.save()
                        break
                    except Exception as e:
                        return http.HttpResponseForbidden('编辑失败')
        return redirect(reverse('goods:info'))

第8次-身份验证

准备环境

1、新建项目chapter08

django-admin startproject chapter08

2、新建应用goods

python manage.py startapp auth_app

3、在setting.py中,已安装app那里添加应用auth_app

4、项目底下创建templates文件夹

在项目的setting.py文件中的BASE_DIR之后追加导包路径:

'DIRS': ['templates'],

5、生成迁移文件并执行迁移,

python manage.py makemigrations
python manage.py migrate

创建User对象

User类提供了创建普通用户的方法create_user()和创建超级用户的方法create()_superuser()。

python manage.py shell

创建普通用户

from django.contrib.auth.models import User
ordinary_user=User.objects.create_user('chapter08','[email protected]','chapter08')
ordinary_user.save()

创建超级用户

super_user=User.objects.create_superuser('admin','[email protected]','admin')
super_user.save()

默认情况下,通过User类创建的用户默认保存在数据表auth_user中。
可以使用User对象的set_password()方法可以修改用户的密码。

from django.contrib.auth.models import User
u=User.objects.get(username='admin')
u.set_password('admin')
u.save()

Web用户登录退出

auth_app/views.py

# 用户登录
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View


class LoginView(View):
    '''登录类视图'''

    def get(self, request):
        return render(request, "login.html")

    def post(self, request):
        """Post方式,用户名登录"""
        username = request.POST['username']  # 用户名
        password = request.POST['password']  # 密码
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)  # 用户登录
            return redirect(reverse('auth_app:index'))
        else:
            return render(request, 'login.html', {
    
    'account_errmsg': '用户名或密码错误'})



class LogoutView(View):
    """退出登录"""

    def get(self, request):
        logout(request)
        # 重定向到登录页面
        return redirect(reverse('auth_app:login'))


# 首页相关视图函数
class IndexView(View):
    '''进入首页'''

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


'''用于保护某个视图函数(函数视图或类视图)只能被已登录的用户访问。
当用户尝试访问该视图函数时,如果用户未登录,
则会被重定向到登录页面,要求其先进行登录操作。'''


@login_required()
def user_center(request):
    return render(request, 'userinfo.html')

在templates文件夹下边新建login.html

<html lang="en" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>

<div style="width:400px;vertical-align:middle;margin: 0 auto;">
    <form method="post">
        {% csrf_token %}
        <td><label>用户名</label></td>
        <td><input type="text" name="username" placeholder="请输入用户名"></td>
        <td><label>密码</label></td>
        <td><input type="password" name="password" placeholder="请输入密码"></td>
        <div style="color:red">{
   
   { account_errmsg }}</div>
        <input type="submit" name="登录" style="height: 30px">

    </form>
</div>
</body>
</html>

templates文件夹下新建index.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<div class="index">
    {% if user.is_authenticated %}
    {
   
   { current_time }}
    欢迎您:<em>{
   
   {user.username}}</em>>
    <span>|</span>
    <a href="{% url 'auth_app:logout' %}" class="quit">退出</a>>
    <span>|</span>
    <a href="{% url 'auth_app:info' %}">用户中心</a>
    {% else %}
    <a href="{% url 'auth_app:login' %}">登录</a>
    {% endif %}
</div>
</body>
</html>

templates文件夹下新建userinfo.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>用户中心页面</p>
<a href="{% url 'auth_app:logout' %}">退出登录</a>
</body>
</html>

配置根路由和子路由

根路由urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('auth_app.urls', namespace='auth_app')),
]

在auth_app应用下新建urls.py文件,子路由auth_app/urls.py代码如下:

from django.urls import path, include

from auth_app import views

app_name = 'auth_app'
urlpatterns = [
    path('login/', views.LoginView.as_view(), name='login'),
    path('info/', views.user_center, name='info'),
    path('index/', views.IndexView.as_view(), name='index'),
    path('logout/', views.LogoutView.as_view(), name='logout')
]

访问服务器,python manage.py runserver
登录,在浏览器中输入 http://127.0.0.1:8000/login/
显示登录成功的首页信息,点击用户中心,进入用户中心界面。

状态保持

Cookie

cookie是什么

Cookie是一小段文本信息,当您访问某个网站时,网站会将一个Cookie文件放置在您的计算机内。Cookie通常包含个人偏好设置、购物车中的商品信息或者一些用于跟踪用户行为的数据。

Cookie的用途有:

  1. 记录用户登录状态,方便用户在下次访问时不必再次输入用户名和密码。

  2. 记录用户偏好设置,如语言和字体大小等。

  3. 跟踪用户行为以用于广告和分析:通过分析cookie中的数据,网站可以更好地了解用户的兴趣和行为,以便提供更好的服务。

  4. 用于购物车:通过管理Cookie,网站可以在用户离开网站时保存他们购物车中的商品列表,便于用户下次继续购买。

  5. 提供个性化内容:通过利用Cookie中的信息,网站可以为每个用户提供相关的个性化内容。

用法

1、创建cookie_app应用,并把应用名添加到setting.py的INASTALLED_APP中。
2、配置路由

并分别在根urls.py和cookie_app/urls.py文件中配置URL。

根urls.py

path('cookie_app/', include('cookie_app.urls')),

cookie_app/urls.py

from django.urls import path, include

from cookie_app import views

urlpatterns = [
    path('set_cookie/', views.set_cookie),
    path('show_cookie/', views.show_cookie),
    path('delete_cookie/',views.delete_cookie)
]

cookie_app/views.py

from django.http import HttpResponse

def set_cookie(request):
    """设置cookie"""
    response = HttpResponse('设置cookie')
    response.set_cookie('python', 'chapter08', max_age=600)
    return response


def show_cookie(request):
    cookie = request.COOKIES.get('python')
    return HttpResponse(f'cookie的值是:{
      
      cookie}')


def delete_cookie(request):
    response = HttpResponse('删除cookie')
    response.delete_cookie('python')
    return response

在浏览器地址栏中输入“http://127.0.0.1:8000/cookie_app/set_cookie/”,此时Cookie已经设置完成,点击浏览器中的“查看网站信息”图标可以打开正在使用的Cookie信息,查看已设置的Cookie。

最后,在浏览器地址栏中输入“http://127.0.0.1:8000/cookie_app/show_cookie/”,此时页面响应Cookie的值。

最后,在浏览器地址栏中输入“http://127.0.0.1:8000/cookie_app/delete_cookie/”,此时通过查看网站信息查看Cookie是否删除。

Session

Session是什么,用途

Session是一种存储在服务器端的用于记录用户信息的机制。HTTP是一种无状态协议,每个请求都是独立的,服务器不知道两个请求是否来自同一个客户端。为了解决这个问题,Session被引入。Session可以存储在服务器端的内存、硬盘、数据库等不同的位置,用户在访问网站时,服务器会为每个访问用户创建一个Session ID,用于标识该用户的Session对象,Session ID会被存储在客户端的Cookie中,并在每个HTTP请求中传递回服务器。

Session的主要用途是记录用户信息,例如用户的登录信息、购物车内容、浏览历史、个人设置等。通过Session,程序可以识别不同的用户,并为每个用户提供个性化的服务。Session还可以用于跨页面传递数据,例如将用户输入数据传递到下一个页面。Session也可以用于实现网站的安全机制,例如记录用户最后一次操作时间,强制用户在一定时间内重新登录,防止非法访问。

Session的用法

1、创建session_app应用,并把应用名添加到setting.py的INASTALLED_APP中。
2、创建视图

session_app/views.py

from django.http import HttpResponse


# Create your views here.
def set_session(request):
    """设置session的name和value,和"""
    request.session['python'] = 'chapter08'
    request.session.set_expiry(8)  # 设置过期时间,8秒
    return HttpResponse('写入session')


# 获取session
def get_session(request):
    value = request.session.get('python')
    return HttpResponse(f"Python对应的 value值为:{
      
      value}")

根路由

path('session_app/', include('session_app.urls'))

session_app/urls.py

from django.urls import path

from session_app import views

urlpatterns = [
    path('set_session/', views.set_session),
    path('get_session/', views.get_session),
]
python manage.py runserver

在浏览器地址栏中输入http://127.0.0.1:8000/session_app/set_session/并按下回车键,此时Session已写入完成。可在数据库中查询到

在浏览器地址中输入“http://127.0.0.1:8000/session_app/get_session/”,可看到Session中key值为“Python”所对应的value值。

猜你喜欢

转载自blog.csdn.net/qq_59621600/article/details/130354516