redis | Django小项目之Mysql数据库和Redis缓存的应用

Django小项目

需求

整体架构图

技术细节

环境配置

  • django-admin startprojrct rmysite1 # 创建项目

  • cd rmysite1 # 进入项目目录

  • python manage.py startapp user # 创建应用

  • mysql 创建数据库 rmysite1 # Navivate 创建数据库 rmysite1

  • Navivate 创建数据库 rmysite1

  • conda 安装 redis包

各文件配置

settings.py
python 复制代码
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

多级路由

python 复制代码
from django.urls import path
from . import views

urlpatterns = [


    # path('user/',include('user.urls')),
    
    path('detail/<int:user_id>',views.user_detail),
    path('update',views.user_update),

]
views.py
python 复制代码
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/1
    cacahe_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.username
    desc = 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 = username
        user.desc = desc  # 只更改desc
        user.save()
        # 删除旧缓存
        cache_key = 'user:%s' %(user.id)
        r.delete(cache_key)

        return HttpResponse('-----update successfully!!!------')
user_update.html
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:是解码后的新字典,可以用于需要普通字符串键和值的场合。

python 复制代码
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'}
相关推荐
layman052844 分钟前
node.js 实战——mongoDB
数据库·mongodb·node.js
爱可生开源社区2 小时前
SQLShift 全新上线:Oracle→OceanBase 迁移利器
数据库
wkj0012 小时前
java 和 C#操作数据库对比
java·数据库·c#
bxlj_jcj2 小时前
如何实现Redis和Mysql中数据双写一致性
redis·缓存·架构
编程在手天下我有2 小时前
Redis 数据类型全览:特性、场景与操作实例
数据库·redis·数据结构与算法
左灯右行的爱情2 小时前
缓存并发更新的挑战
jvm·数据库·redis·后端·缓存
Qiuner3 小时前
软件设计师速通其一:计算机内部数据表示
服务器·数据库·信号处理
文牧之4 小时前
PostgreSQL oracle_fdw 扩展解析
运维·数据库·postgresql
一个天蝎座 白勺 程序猿5 小时前
Python爬虫(9)Python数据存储实战:基于pymysql的MySQL数据库操作详解
数据库·python·mysql