04 用户个人信息和二次开发django的文件存储系统
用户的个人信息的前端页面如下:
业务逻辑分析
从上图中可以看出,需要后端传送的数据有,用户的名字和练习的地址,和最近的浏览记录。
用户的名字和联系的地址可以通过地址表(adress)中获得,地址表可以通过,request.user.address_set获得。
而浏览的记录存在redis中,是因为下次用户退出登陆的时候,浏览的历史记录还在,存储的类型是列表类型,
浏览历史记录 增加 是频繁的 只要访问商品详情页,就要记录信息
查看历史记录,相对访问次数较少只要记录商品的id (sku_id) 就可以 ,保存到内存型数据库里
不放到session数据中,直接操作redis,自己维护数据,是用户下次登录仍然可以看到历史信息
用户id为1的 记录 举例 在redis 中存储的 格式 “history_1”: [1,2,3,4,5].,
取的时候返回的是一个列表.在通过Goodsku表对列表进行取出对应的商品
1 编写个人信息的视图请求的处理函数class UserInfoView:
from django_redis import get_redis_connection
from django_redis import get_redis_connection class UserInfoView(LoginRequiredMixin, View):
"""用户信息页面"""
def get(self, request):
# 获取用户的地址信息
user = request.user
# 获取用户的地址信息,按照创建时间选择最新的一条
try:
address = user.address_set.latest("create_time")
except Address.DoesNotExist:
address = None # 获取用户的浏览历史记录
# 拿到一个redis连接对象
redis_conn = get_redis_connection("default")
# 存在redis中的历史数据是哈希类型
# conn.lrange(“history_1”, 0, 4)
sku_ids = redis_conn.lrange("history_%s" % user.id, 0, 4) # 从数据库中,按照sku id查询商品的信息 # 一次性查出所有数据,顺序变了,所以不采纳
# select * from tbl where id in ()
# skus = GoodsSKU.objects.filter(id__in=sku_ids) skus = []
for sku_id in sku_ids:
sku = GoodsSKU.objects.get(id=sku_id)
skus.append(sku) context = {
# "user": user, # 这个数据可以不用传,在的django中可以直接使用
"skus": skus,
"address": address,
} return render(request, "user_center_info.html", context)
关于Django查询方法的文档:http://python.usyiyi.cn/documents/django_182/ref/models/querysets.html
2 写出个人信息对应的url路径:
url(r'^info$', views.UserInfoView.as_view(), name="info"),
3 前端返回浏览历史的代码如下:
<ul class="goods_type_list clearfix">
{% for sku in skus %}
<li>
<a href="detail.html"><img src="{{ sku.default_image.url }}"></a>
<h4><a href="detail.html">{{ sku.name }}</a></h4>
<div class="operate">
<span class="prize">¥{{ sku.price }}</span>
<span class="unit">{{ sku.price }}/{{ sku.unit }}</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
{% endfor %}
</ul>
==========================================================
说明:
以下的代码是对上面的用户信息进行解释和说明的
下面的代码获取的是用户的最新地址的信息。
try:
address = user.address_set.latest("create_time")
except Address.DoesNotExist:
address = None
下面的这段代码是取出存放在redis中用户浏览的历史数据存放的类型是哈希 ‘键’:[1,2,3,4,5].,通过lrange('键',0,4)返回的是包含5条信息的列表.
在通过便利这个列表,让商品表GoodSKU取出每条商品对应的对象.就可以交给前端展示了.
redis常用的命令: http://redisdoc.com/index.html
python操作redis数据库:http://redis-py.readthedocs.io/en/latest/#indices-and-tables
redis_conn = get_redis_connection("default")
# 存在redis中的历史数据是哈希类型
# conn.lrange(“history_1”, 0, 4)
sku_ids = redis_conn.lrange("history_%s" % user.id, 0, constants.USER_HISTORY_NUM-1) # 从数据库中,按照sku id查询商品的信息 # 一次性查出所有数据,顺序变了,所以不采纳
# select * from tbl where id in ()
# skus = GoodsSKU.objects.filter(id__in=sku_ids) skus = []
for sku_id in sku_ids:
sku = GoodsSKU.objects.get(id=sku_id)
skus.append(sku)
============================================================================================
1.1Django二次开发对接FastDFS
引入python使用fastDFS的基本操作
from fdfs_client.client import Fdfs_client
client = Fdfs_client('/etc/fdfs/client.conf')
ret = client.upload_by_filename('test')
ret
{'Group name':'group1','Status':'Upload successed.', 'Remote file_id':'group1/M00/00/00/
wKjzh0_xaR63RExnAAAaDqbNk5E1398.py','Uploaded size':'6.0KB','Local file name':'test'
, 'Storage IP':'192.168.243.133'}
在django中实现自定义存储系统需要遵循以下步骤:
pip install fdfs_client-py-master.zip
1 你的自定义储存类必须是django.core.files.storage.Storage的子类:
from django.core.files.storage import Storage class MyStorage(Storage):
pass
2 Django必须能够不带任何参数来实例化你的储存类。这意味着任何设置都应该从django.conf.settings中获取
3 你的储存类必须实现 _open() 和 _save()方法,以及任何适合于你的储存类的其它方法。更多这类方法请见下文。
- _open(name, mode='rb')
- pass
被Storage.open()调用,这是储存类用于打开文件的实际工具。它必须返回File对象,在大多数情况下,你会想要返回一些子类,它们实现了后端储存系统特定的逻辑。
- _save(name, content)¶
被Storage.save()调用。name必须事先通过get_valid_name() 和 get_available_name()过滤,并且content自己必须是一个File对象。
详细请参考:http://python.usyiyi.cn/translate/django_182/ref/files/storage.html
http://python.usyiyi.cn/translate/django_182/howto/custom-file-storage.html
在django图片的上传到fastDFS的实现过程
1 创建utils/fastdfs 目录
在fdfs_storage.py 中编写如下的代码:
from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings class FastDFSStorage(Storage):
"""对接fastdfs的文件存储工具类,被django使用"""
def __init__(self, client_conf=None, fastdfs_url=None):
if client_conf is None:
client_conf = settings.FASTDFS_CLIENT_CONF self.client_conf = client_conf if fastdfs_url is None:
fastdfs_url = settings.FASTDFS_URL self.fastdfs_url = fastdfs_url def _save(self, name, content):
"""保存 context是用户上传过来的文件对象"""
# 从文件对象中读取文件数据
file_data = content.read()
# 创建用户存储fastdfs的客户端
client = Fdfs_client(self.client_conf)
# 上传文件内容到fastdfs中
try:
ret = client.upload_by_buffer(file_data)
# ret的返回值格式 {'Group name':'group1','Status':'Upload successed.', 'Remote file_id':'group1/M00/00/00/
# wKjzh0_xaR63RExnAAAaDqbNk5E1398.py','Uploaded size':'6.0KB','Local file name':'test'
# , 'Storage IP':'192.168.228.135'}
except Exception as e:
print(e)
raise if ret.get("Status") == "Upload successed.":
# 表示上传成功
file_id = ret.get("Remote file_id")
# 返回file_id, 也就是文件名,django会保存到数据库中
return file_id
else:
raise Exception("上传到FastDFS失败") def _open(self, name, mode='rb'):
"""打开"""
pass def exists(self, name):
"""判断文件name是否存在"""
return False def url(self, name):
"""返回完整的文件访问url路径"""
# name是文件的名字,也就是file_id
# file_id = "group1/M00/00/00/wKjzh0_xaR63RExnAAAaDqbNk5E1398.py"
# return "http://192.168.228.135/" + name
return self.fastdfs_url + name
2 在配置文件setting中指明修改django的默认文件存储方式
# 修改django的默认文件存储方式
DEFAULT_FILE_STORAGE = 'utils.fastdfs.storage.FastDFSStorage'
fdfs_storage.py中用到的常量放到配置文件中,
# fastdfs服务器的ip地址
FASTDFS_URL = "http://192.168.228.135:8888/"
FASTDFS_CLIENT_CONF = os.path.join(BASE_DIR, "utils/fastdfs/client.conf")
测试fastdfs服务器
启动tracker、storage、nginx服务:
sudo service fdfs_trackerd start sudo service fdfs_storaged start sudo /usr/local/nginx/sbin/nginx
通过admin站点上传一张图图片到一张表中,在python shell 中导入这张表,获取表中的,img字段
在goos应用中的admin中添加以下代码
from django.contrib import admin
from goods.models import GoodsCategory, Goods, GoodsSKU admin.site.register(GoodsCategory)
admin.site.register(Goods)
admin.site.register(GoodsSKU)
登陆admin点击商品分类表,添加一张照片进去
在python manage.py shell中这行以下代码:
from goods.models import GoodsCategory
c = GoodsCategory.objects.get(id=1)
c.image.url
'http://192.168.228.135:8888/group1/M00/00/00/CtM3BVnkILGACHh0AAAmv27pX4k2790330'
在static下面创建一个test.html里面放一个图片的标签路径是上面查询的路径:
<img src='http://192.168.228.135:8888/group1/M00/00/00/CtM3BVnkILGACHh0AAAmv27pX4k2790330'>
在浏览器中输入:
http://127.0.0.1:8000/static/test.html
富文本编辑器
借助富文本编辑器,网站的编辑人员能够像使用offfice一样编写出漂亮的、所见即所得的页面。此处以tinymce为例,其它富文本编辑器的使用也是类似的。
在虚拟环境中安装包
pip install django-tinymce==2.6.0
安装完成后,可以使用在Admin管理中,也可以自定义表单使用。
在setting中配置相应的信息
1. 在settings.py中为INSTALLED_APPS添加编辑器应用
'tinymce', # 富文本编辑器
2在settings.py中添加编辑器配置
# tinymcy配置信息
TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 600,
'height': 400,
}
3 在根级的/urls.py中配置编辑器url
urlpatterns = [ url(r'^tinymce/', include('tinymce.urls')),
]
运行服务器,进入admin后台管理,点击GoodsInfo的添加,效果如下图
04 用户个人信息和二次开发django的文件存储系统的更多相关文章
- TFS二次开发05——下载文件(DownloadFile)
前面介绍了怎样读取TFS上目录和文件的信息,怎么建立服务器和本地的映射(Mapping). 本节介绍怎样把TFS服务器上的文件下载到本地. 下载文件可以有两种方式: using Microsoft.T ...
- CAD二次开发---导入外部文件中的块并输出预览图形(五)
思路: 1)首先要定义一个数据库对象来表示包含块的文件,改数据库对象会被加载到内存中,但不会被显示在CAD窗口中. 2)调用Database类的ReadDwgFile函数将外部文件DWG文件读入到新创 ...
- TFS二次开发09——查看文件历史(QueryHistory)
这篇文章给大家展示怎样获取一个文件的历史版本,内容很简单,直接上代码了. string tpcURL = "http://127.0.0.1:8080/"; TfsTeamProj ...
- NX二次开发-C语言文件读写fwrite和fread函数
NX9+VS2012 #include <uf.h> #include <stdio.h> UF_initialize(); /* //设置文件路径 const char* f ...
- NX二次开发-UFUN判断文件是否存在UF_CFI_ask_file_exist
#include <uf.h> #include <uf_ui.h> #include <uf_cfi.h> UF_initialize(); //判断文件是否存在 ...
- NX二次开发-bat脚本文件切换NX的环境变量(NX路径和语言)
路径环境变量切换到NX9.bat @echo off setx /M UGII_BASE_DIR "D:\Program Files\Siemens\NX 9.0" ------- ...
- TFS二次开发系列索引
TFS二次开发11——标签(Label) TFS二次开发10——分组(Group)和成员(Member) TFS二次开发09——查看文件历史(QueryHistory) TFS二次开发08——分支(B ...
- C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息
在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用 ...
- C#-MVC开发微信应用(7)--在管理系统中同步微信用户分组信息
在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码.希望从一个更高的层次介绍微信的开发. 在 ...
随机推荐
- .NET工具集合
工具 (1) 代码分析 .NET Memory Profiler - http://memprofiler.com/ANTS Profiler - http://www.red-gate.com/co ...
- python中,如有个非常长的字符串,在写的时候如何将其分隔
说明: 比如,有个长字符串,Put several strings within parentheses to have them joined together.但是我在写脚本的时候, 想要放在多行 ...
- SpringMVC由浅入深day01_9商品修改功能开发
9 商品修改功能开发 9.1 需求 操作流程: 1.进入商品查询列表页面 2.点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询) 要修改的商品从数据库查询,根据商品id(主键)查询商 ...
- CentOS 6.3 + Subversion + Usvn 搭建版本管理服务器
一. Subversion 简介 Subversion是一个自由,开源的版本控制系统.在Subversion管理下,文件和目录可以超越时空.Subversion将文件存放在中心版本库里.这个版本库很像 ...
- 在python中重新导入模块
重新加载模块 倘若,更改了已经在 Python shell 中导入的模块,然后重新导入该模块,Python 会认为“我已经导入了该模块,不需要再次读取该文件”,所以更改将无效. 要解决这个问题,有以下 ...
- MSF 内网渗透笔记
进入meterpreter模式 在meterpreter中输入shell即可进入CMD窗口接着即可执行CMD命令,例如打开RDP服务REG ADD HKLM\SYSTEM\CurrentControl ...
- javascript 资料
jQuery 语法实例 $(this).hide() 演示 jQuery hide() 函数,隐藏当前的 HTML 元素. $("#test").hide() 演示 jQuery ...
- Cookie利用神器:CookieHacker
转自evilcos的博客 看到那么多苦逼的跨站师在问Cookie利用工具,不忍心,还是把自己写的Chrome扩展开源出来吧,功能极简,仿造<我的渗透利器>里提到的Original Cook ...
- Python内置性能分析模块timeit
timeit模块 timeit模块可以用来测试一小段Python代码的执行速度. class timeit.Timer(stmt='pass', setup='pass', timer=<tim ...
- C语言变量的存储布局
分析以下代码中变量存储空间如何分配: //MemSeg.c: 代码无意义,仅供分析用 #include <stdio.h> #include <stdlib.h> //mall ...