layout: "post"
title: "用户中心"
date: "2018-04-11 18:12"
用户中心
收货地址
流程:用户发送请求,服务器接受请求后解析url,调取对应的视图函数,先检验是否为用户登录状态,再执行对应的业务逻辑;验证用户登录状态使用django的装饰器,本质是验证session;在django中,装饰器直接装饰get方法,可能影响路由分发逻辑,可以装饰到view()函数的返回值上,即直接装饰到URL中,但是通常不这样做,而是放到views中采取装饰URL的方式添加装饰器;用户登录判断,配合装饰器,需要settings设置,如果用户没有登录,则重定向到settings的路径中。
登录的url,login_required装饰器使用
LOGIN_URL = "/users/login"
装饰器1:
# 装饰URL
from django.contrib.auth.decorators import login_required
login_required(views.AddressView.as_view())
# 装饰器2
# 视图函数继承自这个类
utils/views.py
class LoginRequiredMixin(View):
@classmethod
def as_view(cls,**initkwargs):
view = super(LoginRequiredMixin,cls).as_view(**initkwargs)
return login_required(view)
next参数
这个装饰器附加的参数:next=/users/address;
登录成功,根据next参数跳转页面;
next参数不一定有
next =request.GET.get("next")
if next is None:
return redirect(reverse("goods:index"))
else:
return redirect(next)
url中的参数,使用GET方法获取
参数在请求题中,则根据请求方式选择GET或者POST
URL配置
# /users/urls.py
url(r('^address$',views.AddressView.as_view(),name='address'))
views代码
# /users/views.py
class AddressView(LoginRequiredMixin,View):
def get(self.request):
user = request.user
try:
address = user.address_set.latest("create_time")
# address = Address.objects.filter(user=user).order_by("create_time")[0]
# address = user.address_set.order_by("create_time")[0]
except Address.DoesNotExist:
address = None
return render(request,"user_center_site.html",{"address":address})
def post(self,request):
# 获取参数
user = request.user
recv_name = request.POST.get("recv_name")
detail_addr = request.POST.get("detail_addr")
zip_code = request.POST.get("zip_code")
recv_num = request.POST.get("recv_num")
# 参数校验
# 业务逻辑
if all([recv_name,detail_addr,zip_code,recv_num]):
# address = Address()
# address.user = user
# address.receiver_name = recv_name
# address.detail_addr = detail_addr
# address.zip_code = zip_code
# address.receiver_mobile = recv_num
# address.save()
Address.objects.create(
user = user,
receiver_name = recv_name,
detail_addr =detail_addr,
zip_code = zip_code,
receiver_mobile = recv_num
)
# 返回用户
return redirect(reverse("users:address"))
账号信息与最近浏览
需求产生的时机:当用户访问到商品的详情信息,并且登录,纪录下用户访问过这个商品;
查询:个人信息才有最近浏览信息;
因为产生的次数比较频繁,所以放到内存型数据库中保存sku_id,不放到session数据中,方便用户退出再登录的时候还能查看数据,直接操作redis,存放历史纪录信息;
redis持久化;redis能把保存在内存中的数据定时存储到硬盘中,这个持久化默认开启,可以控制时间间隔;
key:字符串、列表、哈希、set、zset
用一条纪录保存所有人的信息,维护起来不方便,不采纳
'history':{"user_1":string,"user_2":string}
取值:
conn.hget{"history","user_1"}
每个用户一条数据,单独维护
conn.lrange("history_1",0,4)
设置redis
# settings.py
CACHES = {
"default":{
"BACKEND":"django_redis.cache.RedisCache",
"LOCATION":"redis://127.0.0.1/12",
"OPTIONS":{
"CLIENT_CLASS":"django_redis.client.DefaultClient",
}
}
}
# Session
SEESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHS_ALIAS = "dafault"
配置URL
url(r'^info$',views.UserInfoView.as_view(),name='info')
view代码:
from django_redis import get_redis_connection
from goods.models import GoodsSKU
class UserInfoView(LoginRequiredMixin,View):
def get(self,request):
user = request.user
try:
address = user.address_set.latest("create_time")
except:
address = None
redis_conn = get_redis_connection("default")
sku_ids = redis_conn.lrange("history_%s" % user.id,0,4)
skus = []
for sku_id in sku_ids:
sku = GoodsSKU.objects.filter(id=sku_id)
skus.append(sku)
context = {
"address":address,
"skus":skus
}
return render(request,"user_center_info",context)
网友评论