gpt4 book ai didi

python - 使用 __getattr__ 方法扩展 Django 用户模型

转载 作者:太空宇宙 更新时间:2023-11-04 04:36:21 24 4
gpt4 key购买 nike

在 Django 项目中,我有一个扩展 Django 用户模型的模块,类似于以下内容:

from django.contrib.auth.models import User

def __str__(self):
return "%s %s" % (self.first_name, self.last_name)

User.add_to_class('__str__', __str__)

我注意到这行得通。但是,如果我尝试定义一个 __getattr__ 方法,如下所示:

def __getattr__(self, attr):
if self.user_profile:
return getattr(self.user_profile, attr)
else:
raise AttributeError(f"'{self.__class__.__name__}' has no attribute '{attr}'")

导入模块时出现以下错误:

(lucy-web-CVxkrCFK) bash-3.2$ python manage.py shell
Traceback (most recent call last):
File "manage.py", line 28, in <module>
execute_from_command_line(sys.argv)
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/django/core/management/__init__.py", line 347, in execute
django.setup()
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/django/__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/django/apps/registry.py", line 112, in populate
app_config.import_models()
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/site-packages/django/apps/config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/lucy_web/models/__init__.py", line 25, in <module>
from .user import User
File "<frozen importlib._bootstrap>", line 1019, in _handle_fromlist
TypeError: __getattr__() missing 1 required positional argument: 'attr'

难道不能用这种方式用__getattr__方法扩展User模型吗?

最佳答案

在 python 3.7 中,如果您定义一个名为 __getattr__ 的模块级函数 it will be a module level attribute getter function ,类似于类 getattr。看来你是无意的。模块级 __getattr__ 具有与类方法不同的调用签名。

Specification

The __getattr__ function at the module level should accept one argument which is the name of an attribute and return the computed value or raise an AttributeError:

def __getattr__(name: str) -> Any: ...

尝试将函数重命名为其他名称,以避免无意中隐藏保留的函数名称。

def  user_getattr(self, attr):
...

User.add_to_class('__getattr__', user_getattr)

This is mentioned in PEP 562:

This PEP may break code that uses module level (global) names __getattr__ and __dir__. (But the language reference explicitly reserves all undocumented dunder names, and allows "breakage without warning")

And here's what the language reference says:

Any use of __*__ names, in any context, that does not follow explicitly documented use, is subject to breakage without warning.

因此,您还应该重命名您的自定义 __str__ 函数,以避免将来可能出现的损坏。

关于python - 使用 __getattr__ 方法扩展 Django 用户模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51619976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com