A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© gamadi 初级黑马   /  2019-6-6 09:07  /  1038 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

### 判断用户是否登录

#### 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

   

1 个回复

倒序浏览
哇,这位同学大概是学富五车,年薪百万8
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马