Python Django 開発の例外と解決策を見てみましょう
#関連する無料学習の推奨事項:
#1. Django xadmin データ移行エラー ImportError: できません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)
from django.db.models.sql.query import LOOKUP_SEP, QUERY_TERMS は
from django.db.models.sql.query import LOOKUP_SEP, Query## に変更されます# 47 行目の Query: の
if len(parts) > 1 and Parts[-1] を if len(parts) > 1 and Parts[-1] に変更する必要もあります。 ] QUERY_TERMS:
。
Django が xadmin バックグラウンドにログインするとき、ウィジェットを追加するときに、次のようにエラーが報告されます:
return widget.render(TypeError: render() got an unexpected keyword argument 'renderer'
解決策は 2 つあります:
Django ソース コードを変更します- lib\site-packages\django\forms\boundfield を見つけます。 py を実行して、最初の行 96 を見つけます。次のように、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,)
ログイン後にコピー この時点で [予算の追加] をクリックすると、これ以上エラーは報告されません。
- xadmin/views/dashboard.py の
- render()
関数を変更し、36 行目をdef render(self, name) に変更します。 , value, attrs=None, renderer=None):
、つまり、レンダラ パラメータを None に増やします。 どちらの方法も利用できますが、個人的には 2 番目の方法を使用することをお勧めします。xadmin は外部アプリとして extra_apps に外部的に導入されており、特定の変更が加えられている可能性があるため、これに基づいて変更する必要があります。 . 影響は少なく、django は仮想環境からもたらされる依存ライブラリであり、システムファイルに相当しますので、安易に変更しないでください。
データベース マッピングを実行すると、エラーが次のように報告されます:
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.
解決策は、次のように
django.contrib.admin を settings.py の INSTALLED_APPS に追加することです: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">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']</pre><div class="contentsignin">ログイン後にコピー</div></div>
#Django プロジェクトで Restful フレームワークを構成する場合、次のようなエラー __str__ が非文字列 (型 NoneType) を返しました:
これはカスタム ユーザーである可能性があります。モデルが Django に付属のユーザー モデルを置き換える場合、名前 (または同様の) フィールドは空にすることができます。たとえば、
name = models.CharField(max_length=30, null=True、blank=True、verbose_name='name') したがって、非文字列エラーが返されます。完全なモデルは次のとおりです:
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 つあります:
管理者または xadmin のバックグラウンド ログインを終了します。
バックグラウンド管理ログインを終了します。操作は次のとおりです。-
ユーザー モデルの変更__str__()
メソッド - UserProfile などのカスタム ユーザーは AbstractUser を継承しており、AbstractUser モデルには username 属性がありますが、空にすることは許可されていないため、
self.username
を返すように設定できます。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">def __str__(self): return self.username</pre><div class="contentsignin">ログイン後にコピー</div></div>
バックグラウンド管理からログアウトしなくても、通常どおりアクセスできます。
5.DRF が AssertionError を報告します:
basename 引数が指定されていませんRestful フレームワークでフィルターを使用すると、エラーが発生します:
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」パラメータが指定されていません
。明らかに、次のように、ルーターを使用してルートを定義するときに、basename パラメータを指定する必要があります。 :router = DefaultRouter()# 配置goods的路由router.register(r'goods', GoodsListViewSet, basename='goods')
つまり、urls.py に、ルーターを使用してルーティングを構成するときに、basename パラメーターを追加するだけです。
6.UnownedObjectListWarning: ページネーションにより、順序付けされていない object_list と一貫性のない結果が生じる可能性があります。
paginator = self.django_paginator_class(queryset, page_size) Django Restful フレームワークで実装される場合表示すると、特定の種類のデータがページングされ、次のようにフロントエンドがデータへのアクセスを要求すると、警告メッセージが表示されます。
XXX\lib\site-packages\rest_framework\pagination.py:200: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class> QuerySet. paginator = self.django_paginator_class(queryset, page_size)</class>
は、順序付けされていないオブジェクト リストの警告を表示します。これは、データの結果を並べ替えることを意味します。 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 フレームワークで JWT を使用して、カスタム検証 {"non_field_errors":["提供された認証情報を使用してログインできません。"]}
を実装します。最初に宣言します。エディターで使用される Django のバージョンは 3.0 です。これは、後で役立ちます。 DRF で検証を使用する場合、検証には JSON Web トークンがよく使用されます。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
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', ...}
重新加载之后再次访问就会访问到文档页面,如下:
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 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

DockerはLinuxカーネル機能を使用して、効率的で孤立したアプリケーションランニング環境を提供します。その作業原則は次のとおりです。1。ミラーは、アプリケーションを実行するために必要なすべてを含む読み取り専用テンプレートとして使用されます。 2。ユニオンファイルシステム(UnionFS)は、違いを保存するだけで、スペースを節約し、高速化する複数のファイルシステムをスタックします。 3.デーモンはミラーとコンテナを管理し、クライアントはそれらをインタラクションに使用します。 4。名前空間とcgroupsは、コンテナの分離とリソースの制限を実装します。 5.複数のネットワークモードは、コンテナの相互接続をサポートします。これらのコア概念を理解することによってのみ、Dockerをよりよく利用できます。

Pythonは、自動化、スクリプト、およびタスク管理に優れています。 1)自動化:OSやShutilなどの標準ライブラリを介してファイルバックアップが実現されます。 2)スクリプトの書き込み:Psutilライブラリを使用してシステムリソースを監視します。 3)タスク管理:スケジュールライブラリを使用してタスクをスケジュールします。 Pythonの使いやすさと豊富なライブラリサポートにより、これらの分野で優先ツールになります。

VSコードでは、次の手順を通じて端末でプログラムを実行できます。コードを準備し、統合端子を開き、コードディレクトリが端末作業ディレクトリと一致していることを確認します。プログラミング言語(pythonのpython your_file_name.pyなど)に従って実行コマンドを選択して、それが正常に実行されるかどうかを確認し、エラーを解決します。デバッガーを使用して、デバッグ効率を向上させます。

VSコードは、Microsoftが開発した無料のオープンソースクロスプラットフォームコードエディターと開発環境であるフルネームVisual Studioコードです。幅広いプログラミング言語をサポートし、構文の強調表示、コード自動完了、コードスニペット、および開発効率を向上させるスマートプロンプトを提供します。リッチな拡張エコシステムを通じて、ユーザーは、デバッガー、コードフォーマットツール、GIT統合など、特定のニーズや言語に拡張機能を追加できます。 VSコードには、コードのバグをすばやく見つけて解決するのに役立つ直感的なデバッガーも含まれています。

VSコードはPythonの書き込みに使用でき、Pythonアプリケーションを開発するための理想的なツールになる多くの機能を提供できます。ユーザーは以下を可能にします。Python拡張機能をインストールして、コードの完了、構文の強調表示、デバッグなどの関数を取得できます。デバッガーを使用して、コードを段階的に追跡し、エラーを見つけて修正します。バージョンコントロールのためにGitを統合します。コードフォーマットツールを使用して、コードの一貫性を維持します。糸くずツールを使用して、事前に潜在的な問題を発見します。

VSコード拡張機能は、悪意のあるコードの隠れ、脆弱性の活用、合法的な拡張機能としての自慰行為など、悪意のあるリスクを引き起こします。悪意のある拡張機能を識別する方法には、パブリッシャーのチェック、コメントの読み取り、コードのチェック、およびインストールに注意してください。セキュリティ対策には、セキュリティ認識、良好な習慣、定期的な更新、ウイルス対策ソフトウェアも含まれます。
