一个让人很郁闷的问题 DRF

今天在在处理一个嵌套结构API 的时候遇到一个很无语的问题: 开始我这样写,是因为 username 只有一个

   def get_host(self,obj):

    h = User.objects.filter( username = 'wow')
    result = HostSerializer(h)
    return result.data

注意,他的报错信息:

Got AttributeError when attempting to get a value for field `username` on serializer `HostSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'username'.

强制加上 many = True 就好了!没想到只有一个也需要加上 many

    def get_host(self,obj):

    h = User.objects.filter( username = 'wow')
    result = HostSerializer(h,many=True)
    return result.data

DRF 学习笔记

DRF View

Model

from django.db import model

serializer.Serializer  比这个更好的是  serializer.ModelSerializer 

下面是可以继承的mixin

mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,

他们分别对应的前端请求是 比如说 axios.patch

post
get + id 
patch
delete
get + 参数

这是通用的

GenericViewSet 

这是是终极大boss

ModelViewSet

关于过滤

下面是重写 get_queryset 方式获取的过滤功能

def get_queryset(self):
    q = MyApartment.objects.all()

    price_min = self.request.query_params.get("price_min", 0) # 0 是默认值

    if price_min:
        queryset = q.filter(price__gt=int(price_min)) #django 语法
        return queryset

下面是使用filter 文件来过滤

class Roomfilters(django_filters.rest_framework.FilterSet):
'''
房间的过滤类
'''
price_min = django_filters.NumberFilter(name='price',lookup_expr='gte')
price_max = django_filters.NumberFilter(name='price',lookup_expr='lt')
district = django_filters.CharFilter(name='district',lookup_expr='icontains') #前面加i忽略大小写

class Meta:
    model = MyApartment
    fields = ['price_min','price_max','district']

搜索

filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)

search_fields = ('district','rooms')  # ^[email protected]$ 分别代表 startwith /exact match/Full search/ regex

排序

filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)

ordering_fields = ('price')

安装xadmin for Django 2 的时候慢的处理方法

在尝试安装xadmin for Django2 的时候,pip install [email protected] 命令非常慢!不知道怎么办,翻墙太麻烦 后来通过国内的 gitee 中转解决了。。 注意必须用 https 来安装。。

pip install git+https://gitee.com/woooms/django-xadmin-2

还有在配置uwsgi 配置文件的时候老是忘记查看虚拟环境路径的命令

echo $VIRTUAL_ENV

‘list’ object has no attribute ‘rsplit’ admin

当我尝试登录 xadmin的时候报错,而这个错误昨天还没有,我猜和缓存有点关系

‘list’ object has no attribute ‘rsplit’

well, 实际上我自己通过在源码打断点的方式找到了错误原因。。

不知道我为什么在这里加了一个数组。。。我太2了!,下次应该早点从报错的根源哪里打断点开始分析,免得浪费时间
AUTHENTICATION_BACKENDS = (
‘users.views.CustomBackend’,
[‘django.contrib.auth.backends.ModelBackend’] #这是默认的设置
)

Vue-router 入门文章合集

Vue Router 入门总结

在这篇文章里面,作者介绍了路由的两个核心组件

router-link和router-view是两个功能性内置组件。

  • router-link默认被渲染为a标签,负责路由跳转功能;
  • router-view是组件内容被渲染的位置。

动态路由,其实就是路由的时候传参数,发get请求

一个路由渲染多个组件

<router-view class="view one"></router-view>
<router-view class="view two" name="sidebar"></router-view>
<router-view class="view three" name="header"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置(带上 s):

routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: SideBar,
        b: Header
      }
    }
  ]

结合Vuex 和 vue router

虽然我还不知道是什么,但看起来很6..

还有一个入门文章解释的很详细

这一条很有意思

请参考官方文档:
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个index.html 页面,这个页面就是你 app 依赖的页面

DRF Auth的用法

Token的原理:

用户注册的时候,就给绑定一个Token,存到数据库里面,用户在提交表单的时候,需要要header里面增加一个Token

DRM实现Token的流程

*配置 Basic Auth 和 Sessionauth 到 setting.py里面

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework.authentication.SessionAuthentication',
)}

增加app rest-framework.authtoken 到 INSTALLED-APPS 里面

  • 记得执行python manage.py makemigrationspython manage.py migrate‘ 重新生成数据库,这时你应该可以看到数据库新建了一个表叫authtoken-token

在用户注册的时候就给用户一个token

from rest-framework.authtoken.models import Token # 导入Token
token = Token.object.create(user=....)
print(token) # 就可以拿到用户的token了,而且会自动存入数据库!

然后把 token 放到header里面就好

别忘记在urls.py里面urlpatterns的配置一个新的url用于token的校验

re_path(r'^api-token-auth/', views.obtain_auth_token), #这是验证token 的view