最新公告
  • 欢迎您光临吆喝资源网,本站提供站长亲测的网站源码下载,打造专业的源码网!立即加入我们
  • 看看 Python Django开发 异常及解决办法

    相关免费学习推荐:python视频教程

    1.Django xadmin数据迁移报错ImportError: cannot import name ‘QUERY_TERMS’

    在进行Django xadmin数据迁移时报错:

    from django.db.models.sql.query import LOOKUP_SEP, QUERY_TERMS
    ImportError: cannot import name 'QUERY_TERMS' from 'django.db.models.sql.query' (C:/Users/LENOVO/.virtualenvs/Django_Vue_Fresh_Ecommerce-NKba4OvD/lib/site-packages/django/db/models/sql/query.py)

    由于xadmin的更新跟不上Django的更新,因此导致了xadmin的很多代码出错,需要进行修改,这里将xadmin/plugins/filters.py中from django.db.models.sql.query import LOOKUP_SEP, QUERY_TERMS修改为from django.db.models.sql.query import LOOKUP_SEP, Query,还需要将47行的if len(parts) > 1 and parts[-1] in Query:修改为if len(parts) > 1 and parts[-1] in QUERY_TERMS:

    2.Django xadmin报错TypeError: render() got an unexpected keyword argument ‘renderer’

    在Django登录进入xadmin后台时,在添加小部件时,会报错,如下:

    return widget.render(TypeError: render() got an unexpected keyword argument 'renderer'

    解决办法有两种:

    • 修改Django源码
      找到lib/site-packages/django/forms/boundfield.py,找到第96行,注释掉即可,如下:
    return widget.render(
        name=self.html_initial_name if only_initial else self.html_name,
        value=self.value(),
        attrs=attrs,
        # renderer=self.form.renderer,)

    此时再点击Add Budgets就不会再报错了。

    • 修改xadmin代码
      在xadmin/views/dashboard.py中修改render()函数,第36行改为def render(self, name, value, attrs=None, renderer=None):,即增加renderer参数为None。

    两种方法皆可,但是个人建议采用第二种方法,因为xadmin是外部引入到extra_apps作为外部的app,本身就可能经过了一定修改,在此基础上再修改也影响不大,而django是虚拟环境所带的依赖库,相当于是系统文件,因此不要轻易修改。

    3.Django xadmin报错RuntimeError: isn’t in an application in INSTALLED_APPS.

    在进行数据库映射时,报错如下:

    raise RuntimeError(RuntimeError: Model class django.contrib.admin.models.LogEntry doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

    解决办法是在settings.py中的INSTALLED_APPS中增加django.contrib.admin,如下:

    INSTALLED_APPS = [
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'apps.users.apps.UsersConfig',
        'goods',
        'trade',
        'user_operation',
        'DjangoUeditor',
        'xadmin',
        'crispy_forms',
        'django.contrib.admin']

    4.Django配置Restful framework报错__str__ returned non-string (type NoneType)

    在Django项目中配置Restful framework时,报错__str__ returned non-string (type NoneType),如下:
    报错页面4
    这可能是自定义用户模型代替Django自带的用户模型时,允许name(或相似的)字段允许为空,例如name = models.CharField(max_length=30, null=True, blank=True, verbose_name='姓名')所以会返回non-string报错,完整模型如下:

    class UserProfile(AbstractUser):
        '''用户'''
        name = models.CharField(max_length=30, null=True, blank=True, verbose_name='姓名')
        birthday = models.DateField(null=True, blank=True, verbose_name='出生日期')
        gender = models.CharField(max_length=6, choices=(('male', u'男'), ('female', u'女')), default='female',
                                  verbose_name='性别')
        mobile = models.CharField(max_length=11, verbose_name='电话')
        email = models.CharField(max_length=50, null=True, blank=True, verbose_name='邮箱')
    
        is_delete = models.BooleanField(default=False, verbose_name='是否删除')
    
        class Meta:
            verbose_name = '用户'
            verbose_name_plural = '用户'
    
        def __str__(self):
            return self.name

    解决办法有2种:

    • 退出admin或xadmin后台登录
      退出后台管理登录,操作如下:
      django xadmin logout
    • 修改用户模型__str__()方法
      因为自定义用户如UserProfile继承自AbstractUser,而AbstractUser模型有username属性,不允许为空,所以可以设置为返回self.username,即如下:
    def __str__(self):
        return self.username

    此时不登出后台管理也可以正常访问。

    5.DRF报错AssertionError: basename argument not specified

    在Restful framework中使用过滤器时报错:

    assert queryset is not None, '`basename` argument not specified, and could ' /
    AssertionError: `basename` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.queryset` attribute.

    报错提示很明显,assert queryset不是None,未指定“basename”参数,显然需要在使用router定义路由时指定basename参数,如下:

    router = DefaultRouter()# 配置goods的路由router.register(r'goods', GoodsListViewSet, basename='goods')

    即在urls.py中使用router配置路由时加入basename参数即可。

    6.UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list

    paginator = self.django_paginator_class(queryset, page_size)
    在Django Restful framework中实现视图时对某一类数据进行分页并在前端请求访问数据时显示警告信息如下:

    XXX/lib/site-packages/rest_framework/pagination.py:200: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'goods.models.Goods'> QuerySet.
      paginator = self.django_paginator_class(queryset, page_size)

    提示的是无序对象列表警告,意思是对数据结果进行排序,在views.py中取数据时加入排序即可,默认可以按照id进行排序,示意如下:

    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        '''商品列表页,并实现分页、搜索、过滤、排序'''
    
        queryset = Goods.objects.filter(is_delete=False).order_by('id')  # 添加根据id排序即可
        serializer_class = GoodsSerializer
        pagination_class = GoodsPagination
        filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
        filter_class = GoodsFilter
        search_fields = ['name', 'goods_brief', 'goods_desc']
        ordering_fields = ['sold_num', 'shop_price']

    此时再运行,不再显示警告信息。

    7.Django Restful framework中使用JWT实现自定义验证{“non_field_errors”:[“无法使用提供的认证信息登录。”]}

    先声明小编使用的Django版本为3.0,后面有用。
    在DRF中使用验证时经常会使用JSON Web Token进行验证,settings.py配置如下:

    # DRF配置REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
            'rest_framework.authentication.BasicAuthentication',
            'rest_framework.authentication.SessionAuthentication',
        ]}# 自定义用户认证配置AUTHENTICATION_BACKENDS = [
        'users.views.CustomBackend',]

    apps/users/views.py如下:

    from django.db.models import Qfrom django.contrib.auth.backends import ModelBackendfrom django.contrib.auth import get_user_model
    
    
    User = get_user_model()# Create your views here.class CustomBackend(ModelBackend):
        '''自定义用户验证'''
    
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                print(123)
                user = User.objects.get(Q(username=username)|Q(mobile=username))
                if user.check_password(password) and user.is_delete != True:
                    print(456)
                    return user        except Exception as e:
                return None

    urls.py配置如下:

    from rest_framework_jwt.views import obtain_jwt_token
    
    urlpatterns = [
           # JWT认证路由
           url(r'^login/', obtain_jwt_token),]

    但是在模拟请求访问时却未收到token,只提示错误信息{"non_field_errors":["无法使用提供的认证信息登录。"]},这让我很苦恼,明明所有配置都没问题啊,百思不得姐,到底哪里出了问题了呢?一直不停的排错、Debug,却还是一样的错误,这让我很郁闷。最后不得不去求助于JWT官方文档,看到环境要求仿佛有点儿感觉了:

    Requirements
    Python (2.7, 3.3, 3.4, 3.5)
    Django (1.8, 1.9, 1.10)
    Django REST Framework (3.0, 3.1, 3.2, 3.3, 3.4, 3.5)

    这里要求的最高Django版本为1.9,而我自己的Django版本为3.0,凭直觉立马想到会不会是版本不兼容的问题,导致了某些地方不一致。jwt部分就不说了,本身版本没怎么更新,可能问题出在了Django和DRF上面,而最有可能出问题的就是自定义验证类,CustomBackend继承自ModelBackend,于是我到django.contrib.auth.backends源码中查看,其定义如下:

    class ModelBackend(BaseBackend):
        """
        Authenticates against settings.AUTH_USER_MODEL.
        """
    
        def authenticate(self, request, username=None, password=None, **kwargs):
            if username is None:
                username = kwargs.get(UserModel.USERNAME_FIELD)
            if username is None or password is None:
                return
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                # Run the default password hasher once to reduce the timing
                # difference between an existing and a nonexistent user (#20760).
                UserModel().set_password(password)
            else:
                if user.check_password(password) and self.user_can_authenticate(user):
                    return user	...

    为了验证是否是版本的问题,我在系统环境中安装了JWT指定的Django版本1.9用于进行对比,再查看django.contrib.auth.backends.py:

    class ModelBackend(object):
        """
        Authenticates against settings.AUTH_USER_MODEL.
        """
    
        def authenticate(self, username=None, password=None, **kwargs):
            UserModel = get_user_model()
            if username is None:
                username = kwargs.get(UserModel.USERNAME_FIELD)
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
                if user.check_password(password):
                    return user        except UserModel.DoesNotExist:
                # Run the default password hasher once to reduce the timing
                # difference between an existing and a non-existing user (#20760).
                UserModel().set_password(password)

    到现在,你们是否发现了什么(^_^)?

    哈哈,你猜的没错,是新版中的authenticate()方法发生了改变,增加了request参数,而自定义验证类时就是继承ModelBackend类并重写authenticate()方法,而我使用的参数采用的是老版本中的参数,与本应继承的新版本中的方法参数不一致,所以就不是重写是重载了,所以在请求时验证调用的方法并不是自定义的authenticate(),而是ModelBackend类中的authenticate()方法明白怎么回事了就赶紧改了试试,再次测试{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTk1ODk2MTc3LCJlbWFpbCI6IjEyM0AxMjMuY29tIn0.pblxNy4s4XBrqmnsfI9-dmx3Q8rErqq1WbN4rfBSZfI"},一片光明,真是版本不兼容害苦了我,以后得注意了。

    8.Django使用DRF实现注册功能报错Got AttributeError when attempting to get a value

    在使用DRF实现注册功能时,前端的用户名(手机号)、验证码、邮箱传到后端处理时,由于验证码不属于用户的一个字段,但是为了验证又必须设置该字段,如果不注意,就容易报错,一般如下:

    raise type(exc)(msg)AttributeError: Got AttributeError when attempting to get a value for field `code` on serializer `UserRegSerializer`.The serializer field might be named incorrectly and not match any attribute or key on the `UserProfile` instance.Original exception text was: 'UserProfile' object has no attribute 'code'.

    报错提示很明显,UserProfile没有code属性。具体来说,这是因为Meta中指定了fields = ['username', 'code', 'mobile', 'password'],包含code字段,而在验证时为了判断验证码的正误而临时加入code字段,但是在validate(attrs)又将其删去,导致在序列化时找不到code字段,因此出错,这是需要将字段的write_only设置True,以确保在更新或创建实例时可以使用该字段,但是在序列化表示形式时不包括该字段,即设置为如下即可:

    code = serializers.CharField(max_length=4, min_length=4, write_only=True, label='验证码',
        help_text='验证码',
        error_messages={
            'required': '请输入验证码',
            'blank': '请输入验证码',
            'max_length': '请输入4位验证码',
            'min_length': '请输入4位验证码'
        })

    9.DRF访问文档路由报错AttributeError: ‘AutoSchema’ object has no attribute ‘get_link’

    DRF提供了文档功能,无需再专门写文档即可同步使用文档,但是在访问http://127.0.0.1:8000/docs/的时候可能报错:

        link = view.schema.get_link(path, method, base_url=self.url)AttributeError: 'AutoSchema' object has no attribute 'get_link'

    此时需要在settings.py中进行配置:

    # DRF配置REST_FRAMEWORK = {
        ...
        'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
        ...}

    重新加载之后再次访问就会访问到文档页面,如下:
    DRF 文档

    10.DRF动态设置权限

    在DRF中经常会用到权限,一般情况下是在视图ViewSet类下设置属性permission_classes = [IsAuthenticated, IsOwnerOrReadOnly],但是这对于请求的所有方法(如create、retrieve、list)均有效,不能对不同的方法进行不同的限制,因此可以进行动态设置权限,即重写get_permissions()方法,针对不同地方法返回不同的权限,如下:

        def get_permissions(self):
            '''动态设置权限'''
            if self.action == 'retrieve':
                return [IsAuthenticated]
            elif self.action == 'create':
                return []
            return []

    但是会报错如下:

    if not permission.has_permission(request, self):TypeError: has_permission() missing 1 required positional argument: 'view'

    这是因为返回的可能是权限类,即return [IsAuthenticated],这里只是返回了一个权限类,并没有实例化,即没有初始化,导致APIView在初始化时没有传入正确的权限,因此报错,修改为return [IsAuthenticated()]、返回实例化后的对象即可。

    以上就是看看 Python Django开发 异常及解决办法的详细内容,更多请关注吆喝资源网其它相关文章!

    本文转自PHP中文网,吆喝网(http://yaoohe.com)搜集整理,如有疑问请联系本站客服!

    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,默认解压密码为"yaoohe.com",如遇到无法解压的请联系管理员!
    8. 特别声明:本站源码除标明“已测试”外,其它都未测试,有BUG概本站概不负责。
    吆喝资源网 » 看看 Python Django开发 异常及解决办法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    吆喝资源网
    一个高级程序员模板开发平台

    发表评论

    • 6461会员总数(位)
    • 18971资源总数(个)
    • 37本周发布(个)
    • 26 今日发布(个)
    • 1787稳定运行(天)

    专业的网站源码网,提供精品php网站源码下载,小程序源码下载等!!

    小程序源码 了解详情
    升级SVIP尊享更多特权立即升级