Python-Django

181 阅读6分钟

1. 数据库操作

1.1 连接数据库

步骤一:在与项目同名的应用目录下的settings.xml文件中设置数据库信息(本项目使用的是mysql 数据库)

DATABASES = {
    'default':
    {
        'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
        'NAME': 'runoob', # 数据库名称
        'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1
        'PORT': 3306, # 端口
        'USER': 'user',  # 数据库用户名
        'PASSWORD': 'password', # 数据库密码
    }
}

步骤二:在与步骤一settings.xml同级的目录下的__init__.py文件中引入pymysql库

# 在与 settings.py 同级目录下的 __init__.py 中引入模块和进行配置  
import pymysql  
pymysql.install_as_MySQLdb()

步骤三:创建新的应用,Django要求数据模型要单独在一个应用中,并把应用名字加入到settings.xml中的INSTALLED_APPS,如: image.png 步骤四:在命令行中运行

$ python3 manage.py migrate   # 创建表结构
$ python3 manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
$ python3 manage.py migrate TestModel   # 创建表结构

1.2 增删改查

# 增加数据
test1 = Test(name='runoob') 
test1.save()

# 查询数据
# 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM 
list = Test.objects.all() 
# filter相当于SQL中的WHERE,可设置条件过滤结果 
response2 = Test.objects.filter(id=1) 
# 获取单个对象 
response3 = Test.objects.get(id=1) 
# 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2
Test.objects.order_by('name')[0:2] 
# 数据排序 
Test.objects.order_by("id") 
# 上面的方法可以连锁使用 
Test.objects.filter(name="runoob").order_by("id")

# 修改数据
# 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE 
test1 = Test.objects.get(id=1) 
test1.name = 'Google' 
test1.save() 
# 另外一种方式 
Test.objects.filter(id=1).update(name='Google')

# 删除数据
# 删除id=1的数据 
test1 = Test.objects.get(id=1) test1.delete() 
# 另外一种方式 
Test.objects.filter(id=1).delete() 
# 删除所有数据 
Test.objects.all().delete()

1.3 迁移数据库

对model类任何修改,比如新增字段、修改字段类型、删除字段等都需要做数据库迁移,告诉数据库修改了哪些表,需要以下两个命令:

# 让Django知道我们在我们的模型有一些变更
$ python3 manage.py makemigrations 
# 创建表结构
$ python3 manage.py migrate   

2. 创建admin超级管理员页面

参考:#菜鸟教程 Django Admin 管理工具 查询数据示例:

image.png

3. 模板继承

4. 路由分发

  • 存在的问题:网站所有的url都在一个App里面完成分发,比较混乱,难以管理

  • 解决方式:根据path分发到不同的App里面,代码整洁可观,方便后期维护

  • 实现方式:

    1、在每个 app 目录里都创建一个 urls.py 文件。 2、在项目名称目录下的 urls 文件里,统一将路径分发给各个 app 目录。

from django.contrib import admin 
from django.urls import path,include # 从 django.urls 引入 include 
urlpatterns = [ 
    path('admin/', admin.site.urls), 
    path("app01/", include("app01.urls")), 
    path("app02/", include("app02.urls")), 
]

5 Django的Form表单使用说明

6 Django的用户认证组件Auth

6.1 引入

6.2 用户认证

使用authenticate(request, username, password)校验,如果校验成功,返回一个User对象,并创建用户的session;否则返回None

6.3 用户注册登录

  • 注册:本质是在auth_user表里面插入了一条数据,所以调用用户模型的save方法即可实现注册用户;要注意有不同的用户类型
  • create() :创建一个普通用户,密码是明文的。
  • create_user() :创建一个普通用户,密码是密文的。
  • create_superuser() :创建一个超级用户,密码是密文的,要多传一个邮箱 email 参数。
  • 登录:auth.login,登录成功之后会在django_session表里插入一条记录,保存session id;重要:只要执行了auth.login方法,就可以在任何地方通过request.user方法获取当前登录的用户对象(包括在html文件里)
  • @login_required:装饰器,用于限制某些视图必须登录才能访问;用户在访问该页面时,如果未登录,则会跳转到用户登录界面

6.4 用户登出

auth.logout,这个方法干了两件事,一个是清空用户的session信息,一个是将request.user重置为AnonymousUser

N. 问题记录

N.1 CSRF Token Failure问题定位

现象:调用注册接口POST /userprofile/register第一次状态码是302,注册成功并网页重定向,符合预期;刷新网页上再次调用注册用户接口返回403 image.png image.png ps: 用户注册登录系统用的是django.contrib.auth

【复现步骤】

  1. 访问注册页面:http://127.0.0.1:8001/userprofile/register/ (GET /userprofile/register/)
  2. 注册成功(POST /userprofile/register/)
  3. 重定向到articel-list页面(GET /article/article-list/)
  4. 然后点击浏览器的返回页面按钮返回到(不没有任何请求)
  5. 在表单输入合法信息,点击提交按钮(POST /userprofile/register/)
  6. 第六步的请求报错,403 Forbidden

【定位原因】 cookie中的csrf_token与请求体中的csrfmiddlewaretoken不一致

  1. POST /userprofile/register/,生成csrf_token并存储在cookie中
  2. 点击Chrome的返回按钮,回到用户注册界面,但是不刷新界面
  3. 输入表单数据注册POST /userprofile/register/,请求体带的csrfmiddlewaretoken与cookie中的csrf_token一致才能校验通过

【解决方式】

  1. 关掉Django的csrf_token校验
  2. 刷新网页

image.png

Django中{% csrf_token %}的作用:

在 Django 中,{% csrf_token %} 是一个模板标签,用于防止跨站请求伪造(CSRF)攻击。该标签在渲染 HTML 表单时生成并插入隐藏的输入字段,这个输入字段含有为当前用户会话生成的 CSRF 令牌(token)。

CSRF 攻击是一种网络攻击方式,攻击者通过欺骗用户的浏览器,利用用户在网络应用中的验证信息,发送非用户意图的请求。为了防范 CSRF 攻击,Django 提供了内置的 CSRF 保护机制。当启用这个机制时,它会要求所有影响数据状态的 HTTP POST 请求(通常指创建、更新或删除操作)都必须包含有效的 CSRF 令牌。这种验证确保了请求是由确实认证(authenticated)用户和其有效会话发起的,而不是外源性的。

以下是 {% csrf_token %} 标签的基本用法:

<form method="post">
    {% csrf_token %}
    <!-- 表单元素 -->
</form>

当 Django 的模板引擎处理这个标签时,它会生成如下的 HTML:

<input type="hidden" name="csrfmiddlewaretoken" value="随机生成的令牌值">

这个隐藏的输入字段 csrfmiddlewaretoken 包含了用户会话的 CSRF 令牌值。当表单被提交时,这个令牌会随着表单数据一同发送到服务器,Django 的 CSRF 中间件会检查这个令牌是否有效。

在服务器端,Django 会比较表单提交的 CSRF 令牌与在用户会话中保存的令牌是否匹配。如果两者不匹配或表单没有包含 CSRF 令牌,则 Django 会拒绝这个请求,并返回 403 Forbidden 错误,从而提供保护。

总的来说,{% csrf_token %} 模板标签是 Django 用于确保表单提交安全的关键环节,有助于保护 Web 应用免受 CSRF 攻击。

N.2 Chrome硬性重新加载之后js和css文件,报404

【现象】

image.png

【解决方式】

在项目的setting文件中设置DEBUG = True

【原因】 image.png

N.3 model如何保存数据到数据库

  • save():当你调用save()方法时,Django会执行SQL语句将模型实例的数据插入(对于新创建的对象)或更新(对于已存在的对象)到数据库中。如果该模型实例的主键(通常是id字段)已经存在于数据库中,save()会执行一个更新操作;如果没有主键,它会执行一个插入操作。
  • save_m2m():方便保存多对多关系的数据。
  • save(commit=False):得到了一个模型实例,但是还没有保存到数据库中;这个操作增加了save操作的灵活性,因为可以在save(commit=False)之后添加一些除表单之外的数据,如: image.png
  • create:不需要调用save()方法,因为create()方法会自动创建一个新的模型实例并保存它到数据库中。