上一篇【Django】Django4.1.2使用xadmin避坑指南调完后,还是继续有问题,没事,咱们继续,必须啃下硬骨头~
文章目录
- 环境
- 问题一:if not ContentType._meta.installed:这一句报错:AttributeError: 'Options' object has no attribute 'installed'
- 问题二:TypeError: never_cache didn't receive an HttpRequest. If you are decorating a classmethod, be sure to use @method_decorator.
- 问题三: return bool(self.request.is_ajax() or self.request.GET.get('_ajax'))报错:AttributeError: 'WSGIRequest' object has no attribute 'is_ajax'
- 问题四:except models.FieldDoesNotExist:报错:AttributeError: module 'django.db.models' has no attribute 'FieldDoesNotExist'
- 问题五:django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 2: 'ifequal'. Did you forget to register or load this tag?
- 问题六:name 'smart_text' is not defined
环境
win10 python3.9.0 django4.1.2
问题一:if not ContentType._meta.installed:这一句报错:AttributeError: ‘Options’ object has no attribute ‘installed’
我还研究了很久啥原因,看了看源码,后来直接看这段代码的意思,就是让把django.contrib.contenttypes
安装到INSTALLED_APPS
中,我检查了一下,安装了呀。
解决办法:直接注释掉,当然这样就没有检查安装django.contrib.contenttypes
的过程了。
# if not ContentType._meta.installed:
# raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in "
# "your INSTALLED_APPS setting in order to use the admin application.")
看源码,Django 2.0.x的源码中Options是有这个属性方法的,3.2.x也有,4.0.x也有。
/django/db/models/options.py
@property
def installed(self):
return self.app_config is not None
在Django的release note中没有看到提及,看GitHub的代码历史,是被移除了,说没用。
问题二:TypeError: never_cache didn’t receive an HttpRequest. If you are decorating a classmethod, be sure to use @method_decorator.
这个exception好像还没解决,点击这个链接反馈,加速fix
我是注释掉了:
# if not hasattr(request, "META"):
# raise TypeError(
# "never_cache didn't receive an HttpRequest. If you are "
# "decorating a classmethod, be sure to use @method_decorator."
# )
问题三: return bool(self.request.is_ajax() or self.request.GET.get(‘_ajax’))报错:AttributeError: ‘WSGIRequest’ object has no attribute ‘is_ajax’
这个Django 3.1的release note有提到
The HttpRequest.is_ajax() method is deprecated as it relied on a jQuery-specific way of signifying AJAX calls, while current usage tends to use the JavaScript Fetch API. Depending on your use case, you can either write your own AJAX detection method, or use the new HttpRequest.accepts() method if your code depends on the client Accept HTTP header.
If you are writing your own AJAX detection method, request.is_ajax() can be reproduced exactly as request.headers.get(‘x-requested-with’) == ‘XMLHttpRequest’.
可以像这样用,创建一个自定义函数,进行检查:
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
网上的例子:
from django.shortcuts import HttpResponse
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
def ajax_test(request):
if is_ajax(request=request):
message = "This is ajax"
else:
message = "Not ajax"
return HttpResponse(message)
解决方法:
# return bool(self.request.is_ajax() or self.request.GET.get('_ajax'))
return bool(self.request.headers.get('x-requested-with') == 'XMLHttpRequest' or self.request.GET.get('_ajax'))
当我解决完这个问题的时候,真心建议别用Django4尝试搭配xadmin了。😢想完全适配没那么容易。
问题四:except models.FieldDoesNotExist:报错:AttributeError: module ‘django.db.models’ has no attribute ‘FieldDoesNotExist’
解决方法:
最上面导包的代码
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
改成
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, FieldDoesNotExist
报错的那个位置改成
# except models.FieldDoesNotExist:
except FieldDoesNotExist:
问题五:django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 2: ‘ifequal’. Did you forget to register or load this tag?
解决方法:找到报错的模板文件,我报错的是项目根路径/venv/Lib/site-packages/xadmin/templates/xadmin/includes/pagination.html
把ifequal a b 改成 if a == b
把endifequal 改成 endif
问题六:name ‘smart_text’ is not defined
在使用过程中还会有多处报这个错误,或者类似的,因为新的Django没有这个方法了,改成了force_str
和smart_str
。就照着下面对比着改,缺哪个改哪个。
解决方法:
from django.utils.encoding import force_str, smart_str
force_text = force_str
smart_text = smart_str
可以用了!
我把改好的xadmin源码上传了一份到GitHub上,希望能够给个star⭐️!
Django4.1.2-xadmin