用户中心


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)

你可能感兴趣的:(用户中心)