web后端--Django学习笔记09

一、第八天作业

1、在注册表单中包括用户名、密码、性别、爱好(可以有多个),还要完成上传头像,要求在服务器完成接收数据,并保存到服务器。

1.1 代码演示

1、views

from django.http import HttpResponse
from django.shortcuts import render
import os
​
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
​
def go_register(request):
    return render(request,'homework/register.html')
​
​
def register(request):
    regname = request.POST["regname"]
    regpwd = request.POST["regpwd"]
    sex = request.POST["sex"]
    hobbies = request.POST.getlist("hobby")   # 接收一组参数
    your_figure = request.FILES.get("your_figure")
    print("注册名是:"+regname)
    print("注册密码是:" + regpwd)
    print("注册性别是:" + sex)
    print("您的爱好是:",hobbies)
    dest_path = os.path.join(BASE_DIR,'upload','images',your_figure.name)
​
    with open(dest_path,'wb') as f:
        for chunk in your_figure.chunks():
            f.write(chunk)
​
    return HttpResponse("注册成功!")

2、templates

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
    <form action="{% url 'home:register' %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        注册用户名:<input type="text" name="regname"/> <br/>
        注册密码:<input type="password" name="regpwd"/> <br/>
        性别:男:<input type="radio" name="sex" value="boy" checked="checked"/>
             女:<input type="radio" name="sex" value="girl"/> <br/>
        爱好:读书<input type="checkbox" name="hobby" value="read"/> &nbsp;&nbsp;
            电影<input type="checkbox" name="hobby" value="movie"/> &nbsp;&nbsp;
        跑步<input type="checkbox" name="hobby" value="jogging"/> &nbsp;&nbsp;
            美食<input type="checkbox" name="hobby" value="food"/> &nbsp;&nbsp;
          音乐<input type="checkbox" name="hobby" value="music"/> &nbsp;&nbsp;
        个人头像:<input type="file" name="your_figure"/> <br/>
        <input type="submit" value="注册"/>
    </form>
</body>
</html>

3、urls

#子路由
from django.urls import path
​
from homework.views import *
​
app_name = 'homework'
​
urlpatterns = [
    path('goreg/',go_register),
    path('register/',register,name="register"),
]
#总路由
 path('homework/',include('homework.urls',namespace='home')),

二、Django数据库缓存

    第一步:创建缓存表
    python manage.py createcachetable 自定义缓存表名称
例:python manage.py createcachetable mycachetable
第二步:
在settings.py中设置缓存为数据库表
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': '缓存表名称',
    }
}
​
第三步:程序操作
def get_product_byid(request,product_id):
    # 使用底层from django.core.cache import cache查询缓存
     product = cache.get("key")
if 缓存中存在:
    缓存命中,直接返回
else:
    product = Product.objects.get(id=product_id)   # 从数据库中查询
    cache.set("key",product,"可以传入缓存过期时间")  # 保存到缓存表中
    return 返回给客户端

2.1 代码演示

1、setting

​
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'mycachetable',
    }
}
#更改时区
TIME_ZONE = 'Asia/Shanghai'   #亚洲上海
​
USE_I18N = True
​
USE_L10N = True
​
USE_TZ = False    #否定默认时区

2、models

from django.db import models
​
class Product(models.Model):
    name = models.CharField(max_length=20)
    price = models.FloatField()
​
    class Meta:
        db_table = 'products'

3、views

from django.core.cache import cache
from django.shortcuts import render
from django.views.decorators.cache import cache_page
​
from cacheapp.models import Product
​
def get_product_byid(request,product_id):
    product = cache.get('product:'+str(product_id))  # 使用底层API查询缓存
    if product:
        msg = "恭喜,缓存命中了"
    else:
        product = Product.objects.get(id=product_id)   # 从数据库中查询
        msg = "缓存中没找到,只有查数据库了!"
        cache.set('product:'+str(product.id),product,30)  # 保存到缓存表中
    return render(request, 'cacheapp/product.html', locals())
​
​
# @cache_page(30)      #装饰器,定义缓存过期时间
def get_all_products(request):   #查询所有产品
    print("准备查询所有产品~~~")
    products = Product.objects.all()
    print("已经查询完毕所有产品~~~")
    return render(request,'cacheapp/all_products.html',locals())

4、templates

<!product.html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>产品模板</title>
</head>
<body>
    <h3 style="color:red">{{ msg }}</h3>
    <h3>产品编号:{{ product.id }}</h3>
    <h3>产品名称:{{ product.name }}</h3>
    <h3>产品价格:{{ product.price }}</h3>
</body>
</html>
<!all_products.html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>所有产品信息</title>
</head>
<body>
    <table align="center" border="1">
        <thead>
           <tr>
               <th>产品编号</th>
               <th>产品名称</th>
               <th>产品价格</th>
           </tr>
        </thead>
        <tbody>
           {% for product in products %}
               <tr>
                  <td> {{ product.id }} </td>
                  <td> {{ product.name }} </td>
                  <td> {{ product.price }} </td>
               </tr>
           {% endfor %}
        </tbody>
    </table>
</body>
</html>

5、urls

#子路由
from django.urls import path
from cacheapp.views import *
​
urlpatterns = [
    path('product/<int:product_id>/',get_product_byid),
    path('products/',cache_page(30)(get_all_products)),
    path('allproducts/',get_all_products),
]
#总路由
 path('cacheapp/',include('cacheapp.urls')),

6、MySQL

mysql> create database mydb default character set utf8;
Query OK, 1 row affected (0.01 sec)
​
mysql> use mydb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
​
Database changed
mysql> desc mycachetable; #查看创建的缓存表
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| cache_key | varchar(255) | NO   | PRI | NULL    |       |
| value     | longtext     | NO   |     | NULL    |       |
| expires   | datetime(6)  | NO   | MUL | NULL    |       |
+-----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
​
mysql> insert into products(name,price)values('电脑',6000),('箱子',60);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0
​
mysql> select * from products;
+----+--------+-------+
| id | name   | price |
+----+--------+-------+
|  1 | 电脑   |  6000 |
|  2 | 箱子   |    60 |
+----+--------+-------+
2 rows in set (0.00 sec)
​
mysql> select * from mycachetable\G;
*************************** 1. row ***************************
cache_key: :1:product:1
    value: gASVyQAAAAAAAACMFWRqYW5nby5kYi5tb2RlbHMuYmFzZZSMDm1vZGVsX3VucGlja2xllJOUjAhjYWNoZWFwcJSMB1Byb2R1Y3SUhpSFlFKUfZQojAZfc3RhdGWUaACMCk1vZGVsU3RhdGWUk5QpgZR9lCiMBmFkZGluZ5SJjAJkYpSMB2RlZmF1bHSUdWKMAmlklEsBjARuYW1llIwG55S16ISRlIwFcHJpY2WUR0C3cAAAAAAAjA9fZGphbmdvX3ZlcnNpb26UjAUyLjEuMpR1Yi4=
  expires: 2018-11-13 21:39:14.000000
*************************** 2. row ***************************
cache_key: :1:product:2
    value: gASVyQAAAAAAAACMFWRqYW5nby5kYi5tb2RlbHMuYmFzZZSMDm1vZGVsX3VucGlja2xllJOUjAhjYWNoZWFwcJSMB1Byb2R1Y3SUhpSFlFKUfZQojAZfc3RhdGWUaACMCk1vZGVsU3RhdGWUk5QpgZR9lCiMBmFkZGluZ5SJjAJkYpSMB2RlZmF1bHSUdWKMAmlklEsCjARuYW1llIwG566x5a2QlIwFcHJpY2WUR0BOAAAAAAAAjA9fZGphbmdvX3ZlcnNpb26UjAUyLjEuMpR1Yi4=
  expires: 2018-11-13 21:39:30.000000
2 rows in set (0.00 sec)
​
ERROR: 
No query specified
​
mysql> 
​

三、缓存页面(视图函数的执行结果)

​ 第一种使用方法: 在视图函数上添加@cache_page(缓存秒数)装饰器,则会对视图结果缓存 指定的秒数。缓存到CACHES指定的缓存地址。

第二种使用方法:
    path("url/",cache_page(缓存秒数)(视图函数名称))
​
注意:cache_page是针对于具体的URL来进行缓存的。

3.1 代码演示 (同2.1)

四、自定义表单类

  1.继承Form类(django.forms.Form),编写表单类
      class RegForm(forms.Form):  # 自定义表单类,继承Form类
          regname = forms.CharField(label="注册用户名",max_length=10)
          regpwd = forms.CharField(label="注册密码",widget=forms.PasswordInput())
          reghome = forms.ChoiceField(label="籍贯",choices=(("1","陕西"),("2","北京"),("3","山东")))
          sex = forms.ChoiceField(label="性别",choices=(("0","男"),("1","女")),widget=forms.RadioSelect())
2. 在视图函数中判断提交方式,对表单做出不同处理
  def register(request):
      if request.method == "POST":
          regform = RegForm(request.POST)  # 将POST数据传入表单对象的构造方法中
          if regform.is_valid():  # 验证表单数据是否有效
              regname = regform.cleaned_data["regname"] # 接收指定表单域的数据
              print("家乡:"+reghome+";性别:",regsex)
              return redirect(reverse("formapp:success",args=(regname,regpwd)))
      else:
          regform = RegForm()   # 实例化一个空的表单对象
          return render(request,'formapp/register.html',{"regform":regform})
​
3. 在模板上渲染表单
   <form action="" method="post">
    {% csrf_token %}
       {{ regform.as_p }}   显示表单对象封装的表单控件
    <input type="submit" value="注册"/>
   </form>

4.1 代码演示

1、forms.py

from django import forms
​
class RegForm(forms.Form):  # 自定义表单类,继承Form类
    regname = forms.CharField(label="注册用户名",max_length=10)
    regpwd = forms.CharField(label="注册密码",widget=forms.PasswordInput())
    reghome = forms.ChoiceField(label="籍贯",choices=(("1","陕西"),("2","北京"),("3","山东")))
    sex = forms.ChoiceField(label="性别",choices=(("0","男"),("1","女")),widget=forms.RadioSelect())

2、views

from django.shortcuts import render, redirect
from django.urls import reverse
​
from formapp.forms import RegForm
​
def go_success(request,regname,regpwd):
    return render(request,'formapp/success.html',locals())
​
​
def register(request):
    if request.method == "POST":
        regform = RegForm(request.POST)  # 将POST数据传入表单对象的构造方法中
        if regform.is_valid():  # 验证表单数据是否有效
            regname = regform.cleaned_data["regname"] # 接收指定表单域的数据
            regpwd = regform.cleaned_data["regpwd"]
            reghome = regform.cleaned_data["reghome"]
            regsex = regform.cleaned_data["sex"]
            print("家乡:"+reghome+";性别:",regsex)
            return redirect(reverse("formapp:success",args=(regname,regpwd)))
    else:
        regform = RegForm()   # 实例化一个空的表单对象
        return render(request,'formapp/register.html',{"regform":regform})

3、templates

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
    <form action="" method="post">
        {% csrf_token %}
           {{ regform.as_p }} <!以p标签展示>
​
        <input type="submit" value="注册"/>
    </form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>成功页面</title>
</head>
<body>
    <h3> 注册成功,注册的用户名是:{{ regname }},密码是:{{ regpwd }} </h3>
</body>
</html>

4、urls

from django.urls import path,include
from formapp.views import *
​
app_name = "formapp"
​
urlpatterns = [
    path('register/',register,name="register"),
    path('gosuccess/<regname>/<regpwd>/',go_success,name="success"),
]

五、自定义错误页面

    在项目的总路由配置文件中将默认的错误处理程序设置为自定义的视图函数
    eg: 
    from django.conf.urls import handler500
    handler500 = 自定义视图函数名称
​
]注意:两个设置
      在settings.py中,要将调试状态关闭,并设置ALLOWED_HOSTS:
      DEBUG = False
      ALLOWED_HOSTS = ["*"]
​
如果使用的是Django自带的开发服务器,则不能直接在自定义的错误页面中
加载静态资源;如果要加载静态资源,需要使用
"python manage.py runserver --insecure"命令启动开发服务器。

5.1 代码演示

1、urls

#子路由
from django.urls import path
​
from errorapp.views import *
​
urlpatterns = [
    path('error/',error_view),
    path('miss/',error_404),
]
#总路由
from django.conf.urls import handler500, handler404
from django.contrib import admin
from django.urls import path,include
from errorapp.views import myhandler500,myhandler404
​
handler500 = myhandler500
handler404 = myhandler404
​
urlpatterns = [
    path('admin/', admin.site.urls),
   
    path('errorapp/',include('errorapp.urls')),
]

2、views

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
​
​
def error_view(request):
    5 / 0
    return HttpResponse("Hello")
​
def error_404(request):
    return HttpResponseRedirect("/abc/")
​
def myhandler500(request):
    return render(request,'errorapp/my500.html')
​
def myhandler404(request):
    return render(request,'errorapp/my404.html')
​

3、templates

<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>500</title>
</head>
<body>
    <h3>发生一点小故障~~~</h3>
    <img src="{% static 'errorapp/images/ren.gif' %}"/>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_42569562/article/details/84063118