如何正确地为 Django 的用户模型添加权限?
Posted
技术标签:
【中文标题】如何正确地为 Django 的用户模型添加权限?【英文标题】:How correctly add permissions to User model of Django? 【发布时间】:2018-05-06 22:54:50 【问题描述】:我正在尝试将自定义权限添加到 User
模型 (django.contrib.auth.models
)。
我添加到我的users
应用程序的__init__.py
文件:
from django.db.models.signals import pre_migrate
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import Permission
from django.conf import settings
from django.dispatch import receiver
@receiver(pre_migrate, sender=auth_models)
def add_user_permissions(sender, **kwargs):
content_type = ContentType.objects.get_for_model(settings.AUTH_USER_MODEL)
Permission.objects.get_or_create(codename='view_user', name=' Can view users', content_type=content_type)
Permission.objects.get_or_create(codename='change_user_password', name=' Can change user password', content_type=content_type)
settings.py:
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.forms',
'django_select2', # "django-select2" application
'custom_app', # "custom_app" application
'custom_app_2', # "custom_app_2" application
'modeltranslation', # "django-modeltranslation" application
'users', # "users" application
]
错误:
Traceback (most recent call last):
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/utils/autoreload.py", line 228, in wrapper
fn(*args, **kwargs)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
autoreload.raise_last_exception()
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/utils/autoreload.py", line 251, in raise_last_exception
six.reraise(*_exception)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/utils/autoreload.py", line 228, in wrapper
fn(*args, **kwargs)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/apps/registry.py", line 85, in populate
app_config = AppConfig.create(entry)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/apps/config.py", line 94, in create
module = import_module(entry)
File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/Applications/Projects/web/dashboard.kase.kz/users/__init__.py", line 5, in <module>
from django.contrib.contenttypes.models import ContentType
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/contrib/contenttypes/models.py", line 139, in <module>
class ContentType(models.Model):
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/db/models/base.py", line 110, in __new__
app_config = apps.get_containing_app_config(module)
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/apps/registry.py", line 247, in get_containing_app_config
self.check_apps_ready()
File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/apps/registry.py", line 125, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
问题:如何解决此错误?
【问题讨论】:
您需要在 INSTALLED_APPS 中添加permission
。我认为这对你有用。并且还需要添加模型级别权限,即在后端身份验证中。
@Nurzhan Nogerbek 您的项目中的应用程序可能会出现重复条目,例如 users 我猜,还要检查顺序。
我在INSTALLED_APPS
中有'django.contrib.auth'
。 permission
必须在 django.contrib.auth
内,对吧?
@NurzhanNogerbek 我认为您应该在AUTHENTICATION_BACKENDS
中添加django.contrib.auth
和permission.backends.PermissionBackend
,并且permission
需要在已安装的应用程序中。
@ManojJadhav 我按照您的建议将 'permission'
添加到 INSTALLED_APPS
和 AUTHENTICATION_BACKENDS=('permission.backends.PermissionBackend',)
到 settings.py 但在终端中我看到如下错误:ImportError: No module named permission
【参考方案1】:
我终于从documentation找到了解决方案。
1) 您需要使用下一条命令创建空迁移:
python manage.py makemigrations --empty users
用户 - 应用名称
2) 命令创建0001_initial.py
文件,您需要在其中放置下一个代码:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def forwards_func(apps, schema_editor):
User = apps.get_model('auth', 'User')
Permission = apps.get_model('auth', 'Permission')
ContentType = apps.get_model('contenttypes', 'ContentType')
content_type = ContentType.objects.get_for_model(User)
db_alias = schema_editor.connection.alias
Permission.objects.using(db_alias).bulk_create([
Permission(codename='view_user', name=' Can view users', content_type=content_type),
Permission(codename='change_user_password', name=' Can change user password', content_type=content_type)
])
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.RunPython(forwards_func),
]
【讨论】:
【参考方案2】:请尝试在 init.py 文件的顶部添加此代码:
import django
django.setup()
【讨论】:
你能再看看我的帖子吗?我添加了INSTALLED_APPS
的完整设置。顺序正确吗?此外,我添加了您建议的此代码,但随后我尝试在终端中通过python manage.py runserver
命令运行服务器,但没有任何反应。你知道为什么会发生这种情况吗?
更多详情请参考此链接docs.djangoproject.com/en/1.11/ref/applications/…
感谢这个链接;)文档说这个exception is raised when attempting to use models before the app loading process, which initializes the ORM, is complete
。如您所见,在__init__.py
文件中,我只使用了两个模型:ContentType
和Permission
。他们的错误原因?
你能把它们注释掉再检查一遍吗?
我很困惑。我到底需要在__init__.py
文件中评论什么?【参考方案3】:
将 init.py 中的所有代码复制到新创建的名为 signals.py 的文件中,并将 __init__.py
更改为:
default_app_config = 'user.apps.UserConfig'
信号.py
from django.db.models.signals import pre_migrate
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import AuthConfig
from django.contrib.auth.models import Permission
from django.conf import settings
from django.dispatch import receiver
@receiver(pre_migrate, sender=AuthConfig)
def add_user_permissions(sender, **kwargs):
content_type = ContentType.objects.get_for_model(settings.AUTH_USER_MODEL)
Permission.objects.get_or_create(codename='view_user', name=' Can view users', content_type=content_type)
Permission.objects.get_or_create(codename='change_user_password', name=' Can change user password', content_type=content_type)
然后在 user/apps.py 中:
from django.apps import AppConfig
class UserConfig(AppConfig):
name = 'user'
verbose_name = 'User'
def ready(self):
import user.signals
你的错误是occer,因为__init__.py
会在models.py中调用User,但是在__init__.py
运行结束后会注册用户模型,所以你需要在你的用户模型准备好时调用你的信号。
您想添加一些与用户相关的权限:
class MyUser(User):
class Meta:
permissions = (
("view_user", "view_user"),
("change_user_password", "change_user_password"),
)
在settings.py中
AUTH_USER_MODEL = "user.MyUser"
【讨论】:
我使用你的代码。现在没有错误,但是当我运行makemigrations
、migrate
命令时,什么也没有发生。我的意思是没有创建自定义权限 =(signals.py
文件中的代码是否正确?
在文档中我发现了这个:docs.djangoproject.com/en/dev/ref/applications/…,上面写着the database related signals such as pre_migrate and post_migrate are only emitted for applications that have a models module
。 users
应用程序有空的 models.py
文件,因为我使用盒子中的 User
模型。是这种行为的原因吗?
我刚刚注意到您的附加修改。我有一些疑问。我将MyUser
添加到models.py
应用程序的models.py
文件中。这是否意味着您以前的代码现在不需要了?我还添加了您的新代码,但它会引发错误。错误:users.CustomUser.user_ptr: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out. HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.
当我将 settings.py 文件更改为 AUTH_USER_MODEL = "users.models.MyUser"
时,它会引发另一个错误:django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL must be of the form 'app_label.model_name'
。我现在真的很困惑=(
在migrate
、makemigrations
命令之后,您最后的代码还在数据库中创建新模型(新表)吗?以上是关于如何正确地为 Django 的用户模型添加权限?的主要内容,如果未能解决你的问题,请参考以下文章
如何设置 nginx 以正确地为 React 和 Django 提供服务
Django Admin Cookbook-18如何限制对Django Admin管理部分功能的使用