python:django项目知识点01——前期配置、用户管理、权限核验、django-orm

前言

在我一直以来就认为,相比java spring,django"只"适合搭建一个较小的业务系统、或者功能页面。

并且,目前我做的最多的就是:基于三方鉴权的功能性交互页面、一些展示页面、和较小体量的功能系统(也是可以满足一套基本需求的)。

总体而言,它的优势在于:其凭借python胶水代码特性,能够迅速开发并实现扩展性高、功能小巧的的业务系统或功能页面。

知识点

模块安装

pip install Django
pip install django-cors-headers
pip install PyMySQL
pip install djangorestframework

配置settings.py

...
# 是否以测试环境运行
# 生产环境请更换为True
DEBUG = False

# 访问许可,这里*表示接收一切形式的host访问
# 如果你更换为某个域名,将只允许第三方通过该域名访问本系统
ALLOWED_HOSTS = ['*']

# Application definition
# 辅助系统自动识别应用程序,例如

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',  # 添加:跨域组件
    'StaicDjangoDemo',
]

# 中间件配置
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # 跨域中间件,放首行(放其他行未测试)
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware', # 防止跨站请求伪造 (CSRF) 攻击,有些情况会过敏,我不太喜欢这个
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# 配置数据库连接,这里用的是mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database',
        'USER': 'root',
        'PASSWORD': 'xxxxxxx',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

# # 日志
# LOGGING = {
#     'version': 1,
#     'disable_existing_loggers': False,
#     'handlers': {
#         'file': {
#             'level': 'ERROR',
#             'class': 'logging.FileHandler',
#             'filename': 'errors.log',
#             'formatter': 'verbose',
#         },
#     },
#     'formatters': {
#         'verbose': {
#             'format': '%(asctime)s [%(levelname)s] %(message)s',
#             'datefmt': '%Y-%m-%d %H:%M:%S',
#         },
#     },
#     'loggers': {
#         'django': {
#             'handlers': ['file'],
#             'level': 'ERROR',
#             'propagate': True,
#         },
#     },
# }

# 系统时间,这里选用上海时间
TIME_ZONE = 'Asia/Shanghai'

# session设置,存储到database里
SESSION_ENGINE = 'django.contrib.sessions.backends.db'

# 设置每个用户的最大Session数量
MAX_SESSION_PER_USER = 5
# 设置session在浏览器关闭时失效
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
# 设置Session的衰减时间为一天
SESSION_COOKIE_AGE = 86400  # 一天的秒数

# 用户登出跳转的地址
LOGOUT_REDIRECT_URL = '/login'  # 用户登出后重定向到登录页面

# 设置静态文件目录,生产环境建议使用nginx来开放静态文件目录
# 使用【python manage.py collectstatic】指令,将可以把STATICFILES_DIRS内所有的静态文件汇总到STATIC_ROOT中
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'), r'C:\Users\HP\Pictures'
)
STATIC_ROOT = 'staticfiles'


# 跨域忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = ()
# 对应的发送的请求的跨域
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

数据库迁移

需要在settings.py同级目录的__init__.py中添加如下代码,使用pymysql来为django提供mysql数据库服务

import pymysql
pymysql.install_as_MySQLdb()

django系统表迁移至数据库:

利用迁移文件(全量)迁移到数据库:python manage.py migrate

只生成迁移session数据表:python manage.py migrate sessions

只生成迁移auth系统用户数据表:python manage.py migrate auth

根据数据库生成django-orm模型:python manage.py inspectdb > models.py

用户管理

至少将session和auth相关数据表迁移到数据库后,你需要以下脚本来管理用户

这个脚本需要在项目根目录下运行

import os
import django

# 设置 Django 项目的环境变量
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myDemo.settings")
django.setup()

from django.contrib.auth.models import User


def create_user(username, email, password):
    # 检查用户是否已经存在
    if User.objects.filter(username=username).exists():
        print(f"用户 '{username}' 已经存在")
        return

    # 创建新用户
    User.objects.create_user(username=username, email=email, password=password)
    print(f"用户 '{username}' 创建成功")


def update_user_password(username, old, new):
    # 检查用户是否已经存在
    user = User.objects.get(username=username)

    if user:
        # 验证旧密码
        if user.check_password(old):
            # 旧密码正确,设置新密码
            user.set_password(new)
            user.save()
            print(f"Password for user '{username}' changed successfully.")
        else:
            print("Old password is incorrect.")
    else:
        print('username not found')


def delete_user(username):
    # 查找用户
    try:
        user = User.objects.get(username=username)
        user.delete()
        print(f"User '{username}' deleted successfully.")
    except User.DoesNotExist:
        print(f"User '{username}' does not exist.")


# 查询用户的所有信息(密文密码)
def check_users():
    users = User.objects.all()

    for user in users:
        print(f"Username: {user.username}, Email: {user.email}, Password: {user.password}")


if __name__ == "__main__":
    # 替换为你想要创建的用户信息
    # username = "test"
    # email = "xxx@qq.com"
    # password = "username"
    # new_password = 'qnetKPHJ'

    # create_user(username, email, password)
    # update_user_password(username, password, new_password)
    # delete_user('xu')
    check_users()

配置路由urls.py

from django.urls import path, re_path
from django.views import static as sta  # 新增
from .page.public import success
from .page import room, app, user, welcome
from .api import api_app
from django.contrib.auth import views as auth_views

urlpatterns = [
    # 强制开放静态资源,即使在debug为False的情况下,不推荐
    re_path(r'^static/(?P<path>.*)$', sta.serve,
            {'document_root': 'static'}, name='static'),

    # 系统自定义路由,服务页面
    path('welcome', welcome.welcome),
    path('success/room_add', success.success_room_add),
    path('success/app_add', success.success_app_add),
    path('success/register', success.success_register_add),

    path('room/add', room.add_room),
    path('app/add', app.add_app),
    path('app/list', app.app_list),

    path('register/', user.register, name='register'),
    path('login/', user.login_view, name='login'),

    # 用户登出,系统自带服务,登出后跳转至setting.py中的LOGOUT_REDIRECT_URL指定url
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),

    # 这里是restframework api的路由
    path('api/app/list', api_app.AppListView.as_view()),
    path('api/app/list/state', api_app.AppStateFilterView.as_view()),
    path('api/app/detail', api_app.AppAppidFilterView.as_view()),
]

用户权限核验

登录与登出

from django.contrib.auth import authenticate, login, logout

# 登录鉴权验证
user = authenticate(request, username=username, password=password)
if user:
    # 赋予用户授权
    login(request, user)


# 解除用户授权(登出)
logout(request)

身份核验功能

if request.user.is_authenticated:
    # 获取访问者用户名
    username = request.user.username

Django-orm

我比较讨厌规定规格的django-orm,并更喜欢原生sql,但这里还是给出orm的一些操作

模型示例

# 在 myapp/models.py 中
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    isbn = models.CharField(max_length=13, unique=True)

    def __str__(self):
        return self.title

# 使用 .create() 方法
Book.objects.create(
    title="Django for Beginners",
    author="William S. Vincent",
    published_date="2024-01-01",
    isbn="978-0-1234-5678-9"
)

# 或者先创建实例再保存
book = Book(
    title="Django for Experts",
    author="John Doe",
    published_date="2024-02-01",
    isbn="978-1-2345-6789-0"
)
book.save()

# 获取所有 Book 实例
all_books = Book.objects.all()

# 根据条件获取 Book 实例
book_by_title = Book.objects.get(title="Django for Beginners")

# 使用 .filter() 方法
books_by_author = Book.objects.filter(author="William S. Vincent")

# 获取前两个 Book 实例
first_two_books = Book.objects.all()[:2]

# 使用 .exists() 检查某个条件是否存在
exists = Book.objects.filter(title="Django for Beginners").exists()

# 获取要更新的 Book 实例
book = Book.objects.get(title="Django for Beginners")

# 修改字段
book.published_date = "2024-01-15"
book.save()

# 获取要删除的 Book 实例
book = Book.objects.get(title="Django for Beginners")

# 删除实例
book.delete()

# 或者批量删除符合条件的实例
Book.objects.filter(author="John Doe").delete()

自定义sql查询

实用于复杂的查询功能

from django.db import connection


def raw_sql_select(sql, input):
    with connection.cursor() as cursor:
        cursor.execute(sql, input)
        # 获取字段名称
        columns = [col[0] for col in cursor.description]

        # 获取所有行
        rows = cursor.fetchall()

        # 将结果转换为字典列表
        results = [dict(zip(columns, row)) for row in rows]

    return results


# 查询执行进程
processes = raw_sql_select("""
SELECT 
    e.dict_value as state, 
    c.result as res_text, 
    c.appendix as appendix,
    date_format(c.end_time, '%%Y-%%m-%%d %%H:%%i') as process_time
FROM 
    tb_task_process c
JOIN 
    tb_dict e ON c.state = e.dict_id AND e.dict_type = 'process_state'
WHERE 
    c.order_id = %s 
""", [order_id])
print(processes)
相关推荐
老刘莱国瑞12 分钟前
STM32 与 AS608 指纹模块的调试与应用
python·物联网·阿里云
一只敲代码的猪1 小时前
Llama 3 模型系列解析(一)
大数据·python·llama
Hello_WOAIAI2 小时前
批量将 Word 文件转换为 HTML:Python 实现指南
python·html·word
winfredzhang2 小时前
使用Python开发PPT图片提取与九宫格合并工具
python·powerpoint·提取·九宫格·照片
矩阵推荐官hy147622 小时前
短视频矩阵系统种类繁多,应该如何对比选择?
人工智能·python·矩阵·流量运营
测试19982 小时前
外包干了2年,技术退步明显....
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
码银2 小时前
【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割
开发语言·python
小木_.2 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析
R-sz3 小时前
14: curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误“
linux·python·centos
CITY_OF_MO_GY3 小时前
Pytorch常用内置优化器合集
人工智能·pytorch·python