Django Auth:如何创建多对多关系模型?
Django Auth : How are many-to-many relationship models created?
django.contrib.auth.models
只有 3 个模型,User
、Group
、Permission
,根据 doc and code。
文档确实说 groups
和 permissions
是多对多关系。
但是当我们migrate
怎么会创建其他关系user_group
、user_permissions
、group_permissions
?
多对多关系的 table 是由迁移文件中带有 models.ManyToManyField
字符串的行创建的。
在这种情况下,它们是由初始迁移创建的 django/contrib/auth/migrations/0001_initial.py
。它与 django/contrib/auth/models.py
.
非常相似
相关的SQL命令可以被
读取
$ python manage.py sqlmigrate auth 0001_initial
查看行:
CREATE TABLE "auth_user_groups"...
CREATE TABLE "auth_group_permissions"...
CREATE TABLE "auth_user_user_permissions"...
特别有趣的两篇课文围绕着REFERENCES
两个字。那是基础 tables 的外键,例如:
... "user_id" integer NOT NULL REFERENCES "auth_user" ("id") ...
编辑:
您可能知道由参数 through=SomeModel with an extra field 指定的显式中间模型连接的多对多关系。
我在示例中解释了如何在代码中使用隐藏的中间体table。
假设您想对某些权限做一个注释,为什么将它添加给某人。
您可以从命令行探索模型结构,因为在"auth/models.py"中您只能读取名称"user_parmissions".
>>> User._meta.local_many_to_many
[<django.db.models.fields.related.ManyToManyField: groups>,
<django.db.models.fields.related.ManyToManyField: user_permissions>]
>>> User.user_permissions.through
<class 'django.contrib.auth.models.User_user_permissions'>
>>> User.user_permissions.through._meta.local_fields
[<django.db.models.fields.AutoField: id>,
<django.db.models.fields.related.ForeignKey: user>,
<django.db.models.fields.related.ForeignKey: permission>]
your_app/models.py
from django.contrib.auth.models import User, Group, Permission
from django.db import models
# This line is instead of import, because the implicit intermediate table
# can not be imported.
UserPermission = User.user_permissions.through
class UserPermissionReason(models.Model)
user_permission = models.ForeignKey(UserPermission, ...)
reason = models.CharField(help_text="Why I added that permission", ...)
makemigrations,迁移,shell...
示例:使用您的笔记创建用户权限
>>> from your_app.models import UserPermissionReason, UserPermission
>>> from django.contrib.auth.models import User, Group, Permission
>>> permission = Permission.objects.get(name='Can add user',
content_type__app_label='auth')
>>> permission
<Permission: auth | user | Can add user>
>>> user_permission = UserPermission.objects.create(user=me_superuser,
permission=permission)
>>> why = UserPermissionReason.objects.create(
user_permission=user_permission,
reason="Because I can :-)"
)
如果您不需要引用中间值 table,您可以使用普通的简单 some_ruser.user_permissions.add(permission)
django.contrib.auth.models
只有 3 个模型,User
、Group
、Permission
,根据 doc and code。
文档确实说 groups
和 permissions
是多对多关系。
但是当我们migrate
怎么会创建其他关系user_group
、user_permissions
、group_permissions
?
多对多关系的 table 是由迁移文件中带有 models.ManyToManyField
字符串的行创建的。
在这种情况下,它们是由初始迁移创建的 django/contrib/auth/migrations/0001_initial.py
。它与 django/contrib/auth/models.py
.
相关的SQL命令可以被
读取$ python manage.py sqlmigrate auth 0001_initial
查看行:
CREATE TABLE "auth_user_groups"...
CREATE TABLE "auth_group_permissions"...
CREATE TABLE "auth_user_user_permissions"...
特别有趣的两篇课文围绕着REFERENCES
两个字。那是基础 tables 的外键,例如:
... "user_id" integer NOT NULL REFERENCES "auth_user" ("id") ...
编辑:
您可能知道由参数 through=SomeModel with an extra field 指定的显式中间模型连接的多对多关系。
我在示例中解释了如何在代码中使用隐藏的中间体table。
假设您想对某些权限做一个注释,为什么将它添加给某人。
您可以从命令行探索模型结构,因为在"auth/models.py"中您只能读取名称"user_parmissions".
>>> User._meta.local_many_to_many
[<django.db.models.fields.related.ManyToManyField: groups>,
<django.db.models.fields.related.ManyToManyField: user_permissions>]
>>> User.user_permissions.through
<class 'django.contrib.auth.models.User_user_permissions'>
>>> User.user_permissions.through._meta.local_fields
[<django.db.models.fields.AutoField: id>,
<django.db.models.fields.related.ForeignKey: user>,
<django.db.models.fields.related.ForeignKey: permission>]
your_app/models.py
from django.contrib.auth.models import User, Group, Permission
from django.db import models
# This line is instead of import, because the implicit intermediate table
# can not be imported.
UserPermission = User.user_permissions.through
class UserPermissionReason(models.Model)
user_permission = models.ForeignKey(UserPermission, ...)
reason = models.CharField(help_text="Why I added that permission", ...)
makemigrations,迁移,shell...
示例:使用您的笔记创建用户权限
>>> from your_app.models import UserPermissionReason, UserPermission
>>> from django.contrib.auth.models import User, Group, Permission
>>> permission = Permission.objects.get(name='Can add user',
content_type__app_label='auth')
>>> permission
<Permission: auth | user | Can add user>
>>> user_permission = UserPermission.objects.create(user=me_superuser,
permission=permission)
>>> why = UserPermissionReason.objects.create(
user_permission=user_permission,
reason="Because I can :-)"
)
如果您不需要引用中间值 table,您可以使用普通的简单 some_ruser.user_permissions.add(permission)