Django2.1集成xadmin管理后台所遇到的錯誤集錦,解決填坑


django默認是有一個admin的后台管理模塊,但是丑,功能也不齊全,但是大神給我們已經集成好了xadmin后台,我們拿來用即可,但是呢,django已經升級到2.1版本了,xadmin貌似跟不上節奏,那么在集成過程中咱就一步一步填坑吧,這也是一種學習的過程,遇到錯誤,找到錯誤的地方,看看django最新升級都修改了那些,去掉了那些,把相應出錯的地方替換即可。

xadmin源碼地址:https://github.com/sshwsfc/xadmin

下載並解壓:

 

我們用到的是xadmin文件夾,將xadmin復制到項目的根目錄,與項目同級別。

安裝依賴庫:

激活項目的虛擬環境,cd 到解壓的 xadmin-master目錄,運行一下代碼

1
pip3 install  - r requirements.txt

在項目settings.py設置文件中引入:

在項目的urls.py中設置

然后運行:python manage.py makemigrations 建立數據庫遷移文件

這個時候就會引出一系列的錯誤提示

錯誤一:關聯關系ForeignKey引發的錯誤,打開xadmin文件中的模型文件models.py

凡是出現關聯關系字段的地方全部加上 on_delete=models.CASCADE , 如下圖所示:

錯誤二:模塊包名稱合並修改引發的錯誤

錯誤提示:ModuleNotFoundError: No module named 'django.core.urlresolvers' 

這是因為django2.1把from django.core.urlresolvers修改成了django.urls

那么如圖所示將 from django.core.urlresolvers import NoReverseMatch, reverse 

 

修改為:from django.urls import NoReverseMatch, reverse

 

 

錯誤三:出現如下錯誤提示

 

這是因為,django2.1.1的 forms表單初始化僅一個參數,將 forms.Field.__init__(self, required, widget, label, initial, help_text, *args, **kwargs) 修改為如圖所示:

錯誤四:ImportError: cannot import name 'login' from 'django.contrib.auth.views' 

解決辦法:

復制代碼
# 將 website.py 中的
from django.contrib.auth.views import login
from django.contrib.auth.views import logout


# 修改為
from django.contrib.auth import authenticate, login, logout
復制代碼

錯誤五:ImportError: cannot import name 'QUERY_TERMS' from 'django.db.models.sql.query'

 

解決辦法:

1
2
3
4
5
6
7
8
9
10
11
12
13
# django2.1.1版本將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
 
 
# 在Django2.0版本中把
from  django.db.models.sql.query  import  LOOKUP_SEP, QUERY_TERMS
 
# 修改為:
from  django.db.models.sql.query  import  LOOKUP_SEP
from  django.db.models.sql.constants  import  QUERY_TERMS

錯誤六:ModuleNotFoundError: No module named 'django.contrib.formtools'   導入fromtools錯誤,版本太低

解決方案:

1
2
3
4
5
# 卸載舊版本
pip uninstall django - formtools
 
# 安裝新版本
pip install django - formtools

錯誤七:

解決方案:

1
2
3
4
5
# 把xadmin\plugins\password.py中的
from  django.contrib.auth.views  import  password_reset_confirm
 
修改為:
from  django.contrib.auth.views  import  PasswordResetConfirmView

再把位於75行左右  return后的  password_reset_confirm修改為 PasswordResetConfirmView,如下圖所示

 

 錯誤八:AttributeError: 'Settings' object has no attribute 'MIDDLEWARE_CLASSES'

解決辦法:

1
2
3
4
5
6
7
# 將xadmin\plugins\language.py 中的
 
if  settings.LANGUAGES  and  'django.middleware.locale.LocaleMiddleware'  in  settings.MIDDLEWARE_CLASSES:
 
修改為:
 
if  settings.LANGUAGES  and  'django.middleware.locale.LocaleMiddleware'  in  settings.MIDDLEWARE:

最后運行:python manage.py makemigrations 創建遷移數據文件

再運行:python manage.py migrate 遷移數據庫

如果在以上過程中出現類似錯誤,請依照錯誤相應修改,錯誤提示的先后順序或許不一樣,但是請仔細閱讀錯誤提示代碼。

 

錯誤九

ImportError: cannot import name 'QUERY_TERMS'

錯誤日志(error log)

  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "E:\py_virtualenv\joyoo\lib\site-packages\django_filters\__init__.py", line 4, in <module>
    from .filterset import FilterSet
  File "E:\py_virtualenv\joyoo\lib\site-packages\django_filters\filterset.py", line 16, in <module>
    from .filters import (Filter, CharFilter, BooleanFilter, BaseInFilter, BaseRangeFilter,
  File "E:\py_virtualenv\joyoo\lib\site-packages\django_filters\filters.py", line 11, in <module>
    from django.db.models.sql.constants import QUERY_TERMS
ImportError: cannot import name 'QUERY_TERMS'

解決辦法(solution)

source code location:..\Lib\site-packages\django_filters\filters.py

try: from django.db.models.sql.constants import QUERY_TERMS except ImportError: # Django 2.1 QUERY_TERMS = { 'exact', 'iexact', 'contains', 'icontains', 'gt', 'gte', 'lt', 'lte', 'in', 'startswith', 'istartswith', 'endswith', 'iendswith', 'range', 'year', 'month', 'day', 'week_day', 'hour', 'minute', 'second', 'isnull', 'search', 'regex', 'iregex', }

錯誤十:

python報錯 ImportError: cannot import name ‘SKIP_ADMIN_LOG‘ from ‘import_export.admin‘

運行python項目時報錯:ImportError: cannot import name 'SKIP_ADMIN_LOG' from 'import_export.admin'

如下:

打開報錯文件,發現直接紅色提示了。

分析步驟:

1.打開 import_export/admin.py,搜索“SKIP_ADMIN_LOG”,發現確實沒有SKIP_ADMIN_LOG 變量,只有一個方法 get_skip_admin_log(self) ,此方法返回了skip_admin_log,而這個方法是在ImportMixin 類中定義的。

所以猜測,由於版本原因,舊版本中admin.py 是有SKIP_ADMIN_LOG的,新版本中放在了類中。而git上的項目用的是舊版包,我們拉取到本地之后下載的是新包,所以無法引用。

2.此時修改報錯文件的代碼,引入需要的類,用類調用方法,以此獲取變量:

 

錯誤十一

TypeError: argument of type ‘WindowsPath‘ is not iterable - in django python [duplicate]

將setitng里的代碼改一下:

'NAME': BASE_DIR / 'db.sqlite3',

改為

'NAME': str(os.path.join(BASE_DIR, "db.sqlite3"))

之后便是:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': str(os.path.join(BASE_DIR, "db.sqlite3")) } }

問題解決

 

錯誤十二

TypeError: login() got an unexpected keyword argument 'extra_context'暫時解決辦法

直接將xadmin/views/website.py下的原有的website.py文件替換為以下內容即可,新website.py如下:

from __future__ import absolute_import
from django.utils.translation import ugettext as _
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.views.decorators.cache import never_cache
from django.contrib.auth.views import LoginView as login    #與舊的不同
from django.contrib.auth.views import LogoutView as logout  #與舊的不同
from django.http import HttpResponse

from .base import BaseAdminView, filter_hook
from .dashboard import Dashboard
from xadmin.forms import AdminAuthenticationForm
from xadmin.models import UserSettings
from xadmin.layout import FormHelper


class IndexView(Dashboard):
    title = _("Main Dashboard")
    icon = "fa fa-dashboard"

    def get_page_id(self):
        return 'home'


class UserSettingView(BaseAdminView):

    @never_cache
    def post(self, request):
        key = request.POST['key']
        val = request.POST['value']
        us, created = UserSettings.objects.get_or_create(
            user=self.user, key=key)
        us.value = val
        us.save()
        return HttpResponse('')


class LoginView(BaseAdminView):

    title = _("Please Login")
    login_form = None
    login_template = None

    @filter_hook
    def update_params(self, defaults):
        pass

    @never_cache
    def get(self, request, *args, **kwargs):
        context = self.get_context()
        helper = FormHelper()
        helper.form_tag = False
        helper.include_media = False
        context.update({
            'title': self.title,
            'helper': helper,
            'app_path': request.get_full_path(),
            REDIRECT_FIELD_NAME: request.get_full_path(),
        })
        defaults = {
            'extra_context': context,
            # 'current_app': self.admin_site.name,
            'authentication_form': self.login_form or AdminAuthenticationForm,
            'template_name': self.login_template or 'xadmin/views/login.html',
        }
        self.update_params(defaults)
        # return login(request, **defaults)
        return login.as_view(**defaults)(request)   #與舊的不同

    @never_cache
    def post(self, request, *args, **kwargs):
        return self.get(request)


class LogoutView(BaseAdminView):

    logout_template = None
    need_site_permission = False

    @filter_hook
    def update_params(self, defaults):
        pass

    @never_cache
    def get(self, request, *args, **kwargs):
        context = self.get_context()
        defaults = {
            'extra_context': context,
            # 'current_app': self.admin_site.name,
            'template_name': self.logout_template or 'xadmin/views/logged_out.html',
        }
        if self.logout_template is not None:
            defaults['template_name'] = self.logout_template

        self.update_params(defaults)
        # return logout(request, **defaults)
        return logout.as_view(**defaults)(request)    #與舊的不同

    @never_cache
    def post(self, request, *args, **kwargs):
        return self.get(request)

  

 錯誤十三

[Python開發技巧]·解決Django render() got an unexpected keyword argument 'renderer'問題

解決方法如下。

我們啟動項目,進入文章發布頁面。提示出錯:

render() got an unexpected keyword argument 'renderer'

3.jpg

錯誤頁面上有提示,出錯的地方是下面文件的93行。

F:\course\myblog\myblogvenv\lib\site-packages\django\forms\boundfield.py in as_widget, line 93

我這里使用的是最新版本的Django2.1.1所以報錯,解決辦法很簡單。打開這個文件的93行,注釋這行即可。

4.jpg

修改成之后,重新刷新頁面,就可以看到我們的富文本編輯器正常顯示。

錯誤十四

 

記錄 TypeError: render() got an unexpected keyword argument 'renderer' 錯誤

 

在網上看到MXShop這個項目,適合Python, Django + drf 進階的,其中遇到 TypeError: render() got an unexpected keyword argument 'renderer', 在百度一番后發現是Django集成DjangoUeditor,才導致這個錯誤的.網上有什么資料都是去改Django的源文件,但是我覺得這樣很不好,因為部署到新環境的時候,都要手動去改一下Django源文件,這樣太麻煩了

所以打算在DjangoUeditor上找原因,最后居然成功找到了,挺高興的,原因是 DjangoUeditor > widgets.py > UEditorWidget 類,間接繼承 django > forms > widgets.py > Widget 類,而 django > forms > widgets.py > Widget 類

def render(self, name, value, attrs=None, renderer=None): 

這個方法,比之前版本多添加了這個參數 renderer=None

但是,但是,但是!!!
DjangoUeditor > widgets.py > UEditorWidget 類,重寫這個方法 def render(self, name, value, attrs=None),這個 django 在不斷更新,DjangoUeditor卻沒有更新,所以應該把
def render(self, name, value, attrs=None)
改成!!
def render(self, name, value, attrs=None, renderer=None):
 
                  
如圖所示!!!!!!!!!!!

 

錯誤十五

 

xadmin\widgets.py in render, line 81

解決方法:

既然“\n”不能拆分標簽,那么就換一種拆分方式,使用“/><”拆分。

原代碼:

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('\n') if ht != '']

    1

修改后代碼:

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != '']
input_html[0] = input_html[0] + "/>"
input_html[1] = "<" + input_html[1]

 

 

 

 

錯誤十六

問題原因

報錯代碼的目錄
venv\lib\site-packages\xadmin\widgets.py in render, line 80

具體代碼
<div class="datetime clearfix">
上面貼出來的最后一行代碼就是widgets.py的第80行代碼。

問題解決

源代碼:
input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('\n') if ht != '']
修改后的代碼:
 

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != '']

input_html[0] = input_html[0] + "/>"

input_html[1] = "<" + input_html[1]

這只是其中一種方法,如果不能解決問題 請打開以下鏈接地址

此文轉載於http://blog.csdn.net/yuhan963/article/details/79167743

錯誤十七

源代碼:

input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != '']

所在函數換成如下內容:

    def render(self, name, value, attrs=None,renderer=None):
        input_html = [ht for ht in super(AdminSplitDateTime, self).render(name, value, attrs).split('/><') if ht != '']
        zhanwei_one = ""
        zhanwei_two = ""
        if (len(input_html) > 1):
            zhanwei_one = input_html[0] + "/>"
            zhanwei_two = "<" + input_html[1]

        # return input_html
        return mark_safe('<div class="datetime clearfix"><div class="input-group date bootstrap-datepicker"><span class="input-group-addon"><i class="fa fa-calendar"></i></span>%s'
                         '<span class="input-group-btn"><button class="btn btn-default" type="button">%s</button></span></div>'
                         '<div class="input-group time bootstrap-clockpicker"><span class="input-group-addon"><i class="fa fa-clock-o">'
                         '</i></span>%s<span class="input-group-btn"><button class="btn btn-default" type="button">%s</button></span></div></div>' % (zhanwei_one, _(u'Today'), zhanwei_two, _(u'Now')))

 

錯誤十八

 

get_deleted_objects() takes 3 positional arguments but 5 were given

django 的 xadmin 報錯 get_deleted_objects() takes 3 positional arguments but 5 were given

 (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects(
            [self.obj], self.opts, self.request.user, self.admin_site, using)
  • 1
  • 2
  • 改成
      (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects(
            [self.obj], self.request.user, self.admin_site)

錯誤十九

 

xadmin+django2.0刪除用戶報錯,get_deleted_objects() takes 3 positional arguments but 5 were given

 

解決方法:將xadmin/plugins/actions.py中的

復制代碼
        if django_version > (2, 0):
            #deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
               # queryset, self.opts, self.admin_site)
            using = router.db_for_write(self.model)
            deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
                 queryset, self.opts, self.user, self.admin_site, using)
        else:
            using = router.db_for_write(self.model)
            deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
                queryset, self.opts, self.user, self.admin_site, using)
復制代碼

改為

復制代碼
        if django_version > (2, 1):
            deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
                queryset, self.opts, self.admin_site)
            # using = router.db_for_write(self.model)
            # deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
            #     queryset, self.opts, self.user, self.admin_site, using)
        else:
            using = router.db_for_write(self.model)
            deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
                queryset, self.opts, self.user, self.admin_site, using)
復制代碼

 

錯誤二十

django報錯:django.core.exceptions.ImproperlyConfigured: 處理辦法

django報錯:

Eclipse pydev 運行不出錯,cmd 命令行界面中python 運行出錯:

django.core.exceptions.ImproperlyConfigured: 

Requested setting DATABASES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call

 settings.configure() before accessing settings.

解決方法一:

Main代碼中增加;

import os

os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

解決方法二:

命令行運行程序之前運行以下命令或者在bat 批處理文件中增加這句話;

set DJANGO_SETTINGS_MODULE=mysite.settings

 錯誤二十一


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM