Django项目(四)
- 2019 年 10 月 6 日
- 笔记
模板页说明
在一个项目中,我们一般会把相同的内容提取出来作为母版页来使用。我这里是直接下载好的,就不用母版页了。
个人中心页面
个人中心一共有三个页面,我的订单,个人中心,收获地址。我们将这三个页面添加到我们的模板目录下,并且做一个显示在xm_user中view.py添加个类:
# /xm_user
class UserInfoView(View):
# 显示个人中心
def get(self,request):
return render(request,"self_info.html")
# /xm_user/order
class UserOrderView(View):
# 显示订单页
def get(self,request):
return render(request,"dingdanzhongxin.html")
# /xm_user/address
class UserAddressView(View):
# 显示收货地址
def get(self,request):
return render(request,"shouhuadizhi.html")
在urls.py中这三个页面是只有用户登录之后才能显示,所以我们用Django中自带的认证
# 导入模块
from django.contrib.auth.decorators import login_required
from django.conf.urls import url
from xm_user.views import RegisterView,LoginView,ActiveView,UserInfoView,UserOrderView,UserAddressView
urlpatterns = [
# url(r"register$",views.register,name='register'), # 显示注册页面
# url(r'register_handle$',views.register_handle,name='register_handle') # 处理注册页面
url(r'^register$',RegisterView.as_view(),name='register'),
url(r'^active/(.*)$',ActiveView.as_view(),name='active'),
url(r'^login$',LoginView.as_view(),name='login'),
# 用自带的函数认证
url(r'^$',login_required(UserInfoView.as_view()),name='xm_user'),
url(r'^order$',login_required(UserOrderView.as_view()),name='order'),
url(r'^address$',login_required(UserAddressView.as_view()),name='address')
]
这样我们清除cookie之后,再去访问该页面就会跳转到登录页面,Django默认的登录页面是accounts/login,
和我们的不一样,所以我们需要在settings.py中做一下配置,添加配置:LOGIN_URL='/xm_user/login'
这样他就会跳转到我们的登录页面。(记得清除cookie)比如我们的用户在进入我们的个人信息页面的时候,如果没有登录,就会跳转到登录页面,还会添加一个参数next表示我们刚刚访问的个人信息页(xm_user/login?next=/xm_user/),也就是说,用户登录后我们就要让他跳转到个人信息页。这就需要我们在登录验证的时候获取他要跳转的页面,验证成功后跳转,如何获取这个next的值?直接request.GET.get('next')就会获取到/xm_user/,当获取到next的值的时候就跳转该页,获取不到,我们设置
一个默认值也就是主页的url,最后我们在LoginView类中的post中的login(request,u)下添加: next_url = request.GET.get('next',reverse("xm_goods:index"))
我们已经设置默认值所以response = redirect(next_url)这个也需要修改一下,get函数中如果没获取到值不会报错,会给个空值,但是你也可以给他添加第二个函数表示默认值。同样的我们的这三个页面的图片和链接都需要反向解析。上面如果我们很多方法都需要验证是否登录!那我们是不是需要写这个login_required函数写无数遍?
下面我们就来做一个改进:
首先创建在xm_shop下创建一个文件夹utils文件夹, 创建一个py文件名字叫做mixin。
写上:
# 来重写方法
from django.contrib.auth.decorators import login_required
class LoginRequiredMixin(object):
# 静态方法装饰器
@classmethod
def as_view(cls,**initkwargs):
# 调用父类的as_view方法
view = super(LoginRequiredMixin,cls).as_view(**initkwargs)
return login_required(view)
之后我们需要登录之后才能进入的视图,只需要在views.py中的视图类中先继承LoginRequiredMixin,再继承View即可(需要导入)。这样我们的urls.py中还是按照以前的写。二者选其一就好了。
登录之后显示欢迎信息
Django自带判断是否登录:request.user.is_authenticated(),
登录返回true,不是返回false,这个是在后端用,我们前端同样可以使用:
{% if user.is_authenticated %}
<li>欢迎你:{{ user.username }}</li>
<li>|</li>
<li><a href="{ % url 'xm_user:logout' %}" target="_blank">退出</a></li>
<li>|</li>
{% else %}
<li><a href="{ % url 'xm_user:login' %}" target="_blank">登录</a></li>
<li>|</li>
<li><a href="{ % url 'xm_user:register' %}" target="_blank" >注册</a></li>
<li>|</li>
{% endif %}
这样,登录的话就会显示欢迎你:xxx,没有登录就会显示登录和注册。
由于这里没有写成母版页,所以我们需要每个页面都加上这个判断,有兴趣的话可以去把他们相同的部分提取出来作为模板页。
退出功能
在xm_user中views.py中写一个视图类:
#导入logout,清除session
from django.contrib.auth import logout
class LogouView(View):
def get(self,request):
# 清除session信息
logout(request)
return redirect(reverse("xm_goods:index"))
url添加就不说了。
个人中心信息的显示
个人中心显示:用户名,手机号,收货地址
在views.py中的get方法修改成:
def get(self,request):
user = request.user
try:
address = Address.objects.get(user=user, is_default=True)
except Address.DoesNotExist:
address = None
return render(request,"self_info.html",{"address":address})
前端接收即可。
收获地址显示和添加
class UserAddressView(LoginRequiredMixin,View):
# 显示收货地址
def get(self,request):
# 获取当前登录对象
user = request.user
try:
address = Address.objects.get(user=user, is_default=True)
except Address.DoesNotExist:
address = None
return render(request,"shouhuadizhi.html",{"address":address})
def post(self,request):
# 接收数据
name = request.POST.get("name")
addre = request.POST.get("address")
tel = request.POST.get("tel")
check = request.POST.get("check")
if not all([name,addre,tel]):
return render(request,"shouhuadizhi.html",{"errmsg":"有数据为空"})
if not re.match(r'^1[3|4|5|7|8][0-9]{9}$',tel):
return render(request, "shouhuadizhi.html", {"errmsg": "手机号格式不正确!"})
# 获取当前登录对象
user = request.user
try:
address = Address.objects.get(user=user,is_default=True)
except Address.DoesNotExist:
address = None
if check =="on":
if address:
address.is_default = False
address.save()
is_default = True
else:
is_default = False
Address.objects.create(user=user,receiver=name,addr=addre,phone=tel,is_default=is_default)
# 刷新
return redirect(reverse("xm_user:address"))
简单显示了一下,里面有很多重复的方法,完全可以封装在模型管理类中。