### 判断用户是否登录
#### 1.展示用户中心界面
- 需求:
- 当用户登录后,才能访问用户中心。
- 如果用户未登录,就不允许访问用户中心,将用户引导到登录界面。
实现方案:
- 需要判断用户是否登录。
- 根据是否登录的结果,决定用户是否可以访问用户中心。
```python
class UserInfoView(View):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
return render(request, 'user_center_info.html')
```
#### 2.is_authenticate属性判断用户是否处于登录状态
- `is_authenticate`是 request.user对象得到属性,request.user.is_authenticated()通过返回的是true或false判断用户是否处于登录状态
```python
class UserInfoView(View):
"""用户中心"""
def get(self,request):
# 提供个人信息界面
if request.user.is_authenticate():
return render(request,'user_center_info.html') # 判断为登录的时候就跳转到个人中心
else:
return redirect(reverse('users:login')) # 未登录就重定向到登录界面
```
#### 2.login_required装饰器判断用户是否处于登录状态
- Django用户认证系统提供了装饰器
```
login_required
```
来判断用户是否登录。
- 内部封装了`is_authenticate`
- 位置:`django.contrib.auth.decorators`
- 如果通过登录验证则进入到视图内部,执行视图逻辑。
- 如果未通过登录验证则被重定向到
```
LOGIN_URL
```
配置项指定的地址。
- 如下配置:表示当用户未通过登录验证时,将用户重定向到登录页面。
```python
LOGIN_URL = '/login/'
```
> **1.装饰as_view()方法返回值**
>
> 提示:
>
> - `login_required装饰器`可以直接装饰函数视图,但是本项目使用的是类视图。
> - `as_view()`方法的返回值就是将类视图转成的函数视图。
>
> 结论:
>
> - 要想使用`login_required装饰器`装饰类视图,可以间接的装饰`as_view()`方法的返回值,以达到预期效果。
```python
url(r'^info/$', login_required(views.UserInfoView.as_view()), name='info'),
class UserInfoView(View):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
return render(request, 'user_center_info.html')
```
> **2.定义View子类封装login_required装饰器**
>
> - 提示:`LoginRequired(object)`依赖于视图类`View`,复用性很差。
```python
url(r'^info/$', views.UserInfoView.as_view(), name='info'),
class LoginRequired(View):
"""验证用户是否登陆"""
@classmethod
def as_view(cls, **initkwargs):
# 自定义as_view()方法中,调用父类的as_view()方法
view = super().as_view()
return login_required(view)
class UserInfoView(LoginRequired):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
return render(request, 'user_center_info.html')
```
> **3.定义obejct子类封装login_required装饰器**
>
> - 提示:`LoginRequired(object)`不依赖于任何视图类,复用性更强。(在utils.py中创建login.py 文件,写扩展类装饰器,在其中的as_view返回的函数中添加装饰器)
```python
url(r'^info/$', views.UserInfoView.as_view(), name='info'),
from django.contrib.auth.decorators import login_required
class LoginRequired(object):
"""验证用户是否登陆"""
@classmethod
def as_view(cls, **initkwargs):
# 自定义as_view()方法中,调用父类的as_view()方法
view = super().as_view()
return login_required(view)
class UserInfoView(LoginRequired, View):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
return render(request, 'user_center_info.html')
```
> **4.定义验证用户是否登录扩展类**
>
> - 提示:定义扩展类方便项目中导入和使用(`meiduo_mall.utils.views.py`)
```python
class LoginRequiredMixin(object):
"""验证用户是否登录扩展类"""
@classmethod
def as_view(cls, **initkwargs):
# 自定义的as_view()方法中,调用父类的as_view()方法
view = super().as_view()
return login_required(view)
class UserInfoView(LoginRequiredMixin, View):
"""用户中心"""
def get(self, request):
"""提供个人信息界面"""
return render(request, 'user_center_info.html')
```
- 创建area模型类
```shell
class Areas(models.Model):
name = models.CharField(max_length=20)
# 自关联,允许为空,表示关联对象
parent = models.ForeignKey('self', null=True, blank=True, related_name='subs')
#django框架根据外键parent自动创建:parent_id===》关联对象的主键
class Meta:
db_table = 'tb_areas'
verbose_name =
verbose_name_plural -= verbose_name
```
parent表示关联的对象,parent_id表示关联对象的主键(字段中自行生成的,包含内容字段parent和关联id
)
### 收货地址的请求
- 对返回的对象列表,进行前端所需内容,对从数据库内得到的数据进行遍历重构
- 根据项目对接文档得到:***url请求地址,请求方式,实现功能,返回数据格式***
- 第一步:返回省内容的请求,查询数据库parent__isnull=True
- 第二步:前端收到省级信息后,发送ajax请求后,根据第一步查询相对应的市
```python
class Area(View):
def get(self,request):
# 先从缓存中读取地区id:area_id
area_id = request.GET.get('area_id')
if area_id is None:
result = cache.get('province_list')
if result is None:
province_list = Areas.objects.filter(parent__isnull=True)
province_list2 = []
for province in province_list:
province_list2.append({
'id':province.id,
'name':province.name
})
```
- 缓存
- 对于不变的数据,或者变化很小的数据,可以考虑缓存
- 优点:读取速度快
- 缓存的数据库是default(0)数据库
- 实现:cache.set(key,value,expires)存入缓存中 cache.get(key) =>>value ,如果过期返回None
|
|