Django小项目
- 需求
- 整体架构图
- 技术细节
- 环境配置
- 各文件配置
- settings.py
- urls.py
- views.py
- user_update.html
- 结果
- 相关代码补充
- r.hgetall(cacahe_key)
- new_data= {k.decode():v.decode() for k,v in data.items()}
需求
整体架构图
技术细节
环境配置
-
django-admin startprojrct rmysite1 # 创建项目
-
cd rmysite1 # 进入项目目录
-
python manage.py startapp user # 创建应用
-
mysql 创建数据库 rmysite1 # Navivate 创建数据库 rmysite1
-
Navivate 创建数据库 rmysite1
-
conda 安装 redis包
各文件配置
settings.py
INSTALLED_APPS = [...'user', # 加入应用
]# 。。。。DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'rmysite1','USER':'root','PASSWORD':'自己密码','HOST':'127.0.0.1','PORT':'3306',}
}TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR,'templates')], # 在项目目录创建'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = 'Asia/Shanghai'
urls.py
多级路由
from django.urls import path
from . import viewsurlpatterns = [# path('user/',include('user.urls')),path('detail/<int:user_id>',views.user_detail),path('update',views.user_update),]
views.py
from django.http import HttpResponse
from django.shortcuts import render
from .models import User
import redis# 全局变量
r = redis.Redis(host='127.0.0.1',port=6379,db=0,password='123456')# Create your views here.
def user_detail(request,user_id):# user/detail/1cacahe_key = 'user:%s'%(user_id)# 优先查看缓存if r.exists(cacahe_key):data = r.hgetall(cacahe_key)# {b'username':b'xxx',b'desc':b'xxx'} 字节形式# 转换为字符串形式new_data= {k.decode():v.decode() for k,v in data.items()}username = new_data['username']desc = new_data['desc']html = 'cache username is %s ; desc is %s'%(username,desc)return HttpResponse(html)# 没有缓存数据try:user = User.objects.get(id=user_id)except Exception as e:print('-- get user error is %s'%(e))return HttpResponse('-----no user!!!------')username = user.usernamedesc = user.desc# 更新缓存 存储到缓存r.hmset(cacahe_key,{'username':username,'desc':desc})r.expire(cacahe_key,60) # 哈希只能整体加过期时间html = 'mysql username is %s ; desc is %s'%(username,desc)return HttpResponse(html)def user_update(request):if request.method == 'GET':return render(request,'user_update.html')elif request.method == 'POST':username = request.POST['username']desc = request.POST['desc']try:user = User.objects.get(username=username)except Exception as e:print('-- update user error is %s' % (e))return HttpResponse('-----no user!!!------')# user.username = usernameuser.desc = desc # 只更改descuser.save()# 删除旧缓存cache_key = 'user:%s' %(user.id)r.delete(cache_key)return HttpResponse('-----update successfully!!!------')
user_update.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>更新</title>
</head>
<body>
<form action="/user/update" class="action" method="post">{% csrf_token %} <!--- CSRF验证机制 ----><p>用户名:<input type="text" name="username"></p><p>个人描述:<input type="text" name="desc"></p><p><input type="submit" value="更新"></p>
</form>
</body>
</html>
结果
- 第一次运行结果
- 第二次运行
修改个人信息 返回 并从新访问
更新后 立即删除旧缓存数据
更新后的第一次访问:redis缓存没有该信息 mysql数据库查找 并将数据存入redis缓存
更新后的第二次访问 redis缓存数据中存在 直接访问
相关代码补充
r.hgetall(cacahe_key)
在 Redis 中,HGETALL 命令用于获取哈希表中指定键的所有字段和值。
HGETALL 返回一个列表,其中每个字段的值按字段名和值交替排列。例如,如果哈希表包含字段 field1 和 field2,其值分别为 value1 和 value2,则 HGETALL 将返回 [b'field1', b'value1', b'field2', b'value2']
(在某些客户端库中返回的可能是字节字符串)
new_data= {k.decode():v.decode() for k,v in data.items()}
data.items():获取 data 字典的键值对项,返回一个迭代器,每个项是一个元组 (key, value)。
在字典推导式 {k.decode():v.decode() for k,v in data.items()} 中,对于 data.items() 返回的每个键值对 k 和 v:
k.decode():将键 k 从字节字符串解码为普通字符串。如果 k 已经是普通字符串,这个调用将引发 AttributeError。
v.decode():将值 v 从字节字符串解码为普通字符串。如果 v 已经是普通字符串,这个调用同样会引发错误。
{k.decode():v.decode() for k,v in data.items()}:创建一个新字典 new_data,其键和值都是解码后的字符串。
new_data:是解码后的新字典,可以用于需要普通字符串键和值的场合。
data = {b'key1': b'value1',b'key2': b'value2'
}# 使用字典推导式解码所有键和值
new_data = {k.decode(): v.decode() for k, v in data.items()}print(new_data) # 输出: {'key1': 'value1', 'key2': 'value2'}