Django は、逆関係名 (relation_name) を使用して、「多対多」関係によって引き起こされるフィールド名の競合によって引き起こされる移行コマンド エラーを解決します。

パラメータがモデルのリレーションシップ フィールドに追加されるとrelated_name、パラメータで指定された名前を使用して、逆のリレーションシップを参照できます。以下は、逆の関係を参照する方法を示す簡単な例です。

次の 2 つのモデルがあるとします。

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')

上記の例では、Bookモデルには、モデルauthorに関連する外部キー フィールド があります。パラメーターAuthorを追加すると、モデルに逆の関係の名前が として与えられますrelated_name='books'Bookbooks

これで、その逆関係名を使用して、Authorモデルのインスタンス内のそれに関連するオブジェクトのコレクションにアクセスできるようになりますBook例えば:

author = Author.objects.get(pk=1)
books = author.books.all()

上記のコードでは、Authorデータベースからモデルのインスタンスを取得し、books逆関係名によってその著者に関連するすべての書籍オブジェクトにアクセスしました。

パラメーターを使用するとrelated_name、オプションで逆関係の名前を指定して、モデル間を移動し、関連オブジェクトにアクセスできます。

これは、「「多対多」の中間リレーショナル テーブルの逆関係名によって引き起こされる競合を解決するには、逆関係名 (関連名) を使用する」です。

中間リレーションシップ テーブルとは何か、中間リレーションシップ テーブルが存在する理由、および中間リレーションシップ テーブルの逆リレーション名によって引き起こされる競合の詳細な説明については、私の他のテーブル ブログ投稿を参照してください。Django でのデータベース操作メソッドの使用方法を示す実践的な例を通して、ForeignKey()-foreign key in Django [データ テーブル "1 対多" リレーションシップ]、および「中間リレーションシップ テーブル」、逆リレーションシップ (relational_name)、および逆リレーションシップ名の競合の概念を詳しく説明します

E:\Python_project\P_001\myshop-test\myshop_background_2\users\models.py のコードは次のとおりです。

from datetime import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser


class MyUser(AbstractUser):
    SEX = (
        (0, '男'),
        (1, '女'),
    )
    LEVEL = (
        (1, '寂寞卡会员'),
        (2, '钻石卡会员'),
        (3, '金卡会员'),
        (4, '银卡会员'),
    )
    STATUS = (
        (0, '正常'),
        (1, '异常'),
    )

    truename = models.CharField('真实姓名', blank=True, max_length=50)
    mobile = models.CharField('手机号码', max_length=11, default="")
    sex = models.IntegerField(default=0, choices=SEX)
    birthday = models.DateField(blank=True, null=True)
    user_img = models.ImageField("头像", upload_to="user_img", default="")
    level = models.IntegerField(default=4, choices=LEVEL)
    status = models.IntegerField(default=0, choices=STATUS)
    create_time = models.DateTimeField(default=datetime.now, verbose_name='创建时间')
    update_time = models.DateTimeField(default=datetime.now, verbose_name="更新时间")

    def __str__(self):
        return self.username

    class Meta(AbstractUser.Meta):
        permissions = (
            ['check_myuser', '审核用户信息'],
        )

データベース移行コマンド manage.py makemigrations を実行すると、次のエラーが報告されます。

SystemCheckError: System check identified some issues:

ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'auth.User.groups' clashes with reverse accessor for 'users.MyUser.groups'.
        HINT: Add or change a related_name argument to the definition for 'auth.User.groups' or 'users.MyUser.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'auth.User.user_permissions' clashes with reverse accessor for 'users.MyUser.user_permissions'.
        HINT: Add or change a related_name argument to the definition for 'auth.User.user_permissions' or 'users.MyUser.user_permissions'.
users.MyUser.groups: (fields.E304) Reverse accessor for 'users.MyUser.groups' clashes with reverse accessor for 'auth.User.groups'.
        HINT: Add or change a related_name argument to the definition for 'users.MyUser.groups' or 'auth.User.groups'.
users.MyUser.user_permissions: (fields.E304) Reverse accessor for 'users.MyUser.user_permissions' clashes with reverse accessor for 'auth.User.user_permissions'.
        HINT: Add or change a related_name argument to the definition for 'users.MyUser.user_permissions' or 'auth.User.user_permissions'.

groupsエラー メッセージは、およびフィールドに関する競合を示していますuser_permissions


具体的には、 ①auth.User の groups フィールドが users.MyUser のグループと競合する、
② auth.User. の user_permissions フィールドが users.MyUser の user_permissions と競合する、という2 つの競合があります。

質問: auth.User はいつ導入されましたか?
答えは次のコードにあります。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 'basic',
    'users',
]

以下のコード内のステートメントに注目してください。

    'django.contrib.auth',

質問: 明らかに、モジュールには定義groupsやフィールドがありませんuser_permissions
回答: 定義するモデルは、システムに付属するモデルのこれらのフィールドMyUserを継承しAbstractUser継続するため、定義されています。AbstractUserUser

解決:

解決策 1:
アプリケーション 'django.contrib.auth' を settings.py に登録しないでください。ただし、Django 独自のバックグラウンド システムを使用する場合、これは次の理由からお勧めできません: Django では、デフォルトで、アプリケーションは認証とユーザー管理の主要なアプリケーションであり、Django 独自のバックグラウンド管理システムのユーザー認証と権限管理機能を提供し
ますdjango.contrib.authDjango 独自のバックエンド管理システムを使用したい場合は、通常、django.contrib.authアプリケーションを含める必要があります。

settings.pyアプリケーションを設定INSTALLED_APPS含めることで、django.contrib.authバックグラウンド管理システムが正常に動作し、ユーザー認証と権限管理の機能が保証されます。このようにして、ユーザー モデル、ユーザー グループ、権限などの組み込み機能を使用できます。

Django 独自のバックグラウンド管理システムを使用したくない場合、またはすでにカスタム ユーザー管理システムを使用している場合はINSTALLED_APPSdjango.contrib.authそこからアプリケーションを削除することを検討できます。これにより、不要なコードとデータベース テーブルが削減され、プロジェクトがより軽量になります。

ただし、django.contrib.authアプリケーションを削除すると、次のようなユーザー認証と権限に関連する多くの機能が失われることに注意してください。

  • ユーザー認証・ログイン機能
  • ユーザー登録・パスワードリセット機能
  • ユーザー権限と権限管理機能
  • ユーザーグループ管理機能
  • バックグラウンド管理システムのユーザー認証および権限管理機能

django.contrib.authしたがって、アプリケーションを削除するかどうかを決定する前に、代替のユーザー認証および権限管理ソリューションがあることを確認し、関連機能の実装とメンテナンスのコストを考慮してください。

解決策 2:

カスタム モデルのgroupsおよびフィールドの名前を変更します **:user_permissionsカスタム モデルのgroupsおよびフィールドを保持したいが、user_permissions組み込みモデルとのauth.User競合を避けたい場合は、related_nameこれら 2 つのフィールドにパラメータを追加して、別の名前を指定できます。例えば:

from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission


class MyUser(AbstractUser):
	# ...

    groups = models.ManyToManyField(
        Group,
        verbose_name='groups',
        blank=True,
        help_text='The groups this user belongs to.',
        related_name='user_groups'  # 设置不同的 related_name
    )
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name='user permissions',
        blank=True,
        help_text='Specific permissions for this user.',
        related_name='user_permissions'  # 设置不同的 related_name
    )

    
        # ...

カスタム モデルのgroupsフィールドとフィールドにパラメーターをuser_permissions追加し、それらのパラメーターを組み込みモデルのフィールドとは異なる名前related_nameに設定することで、競合を回避できます。auth.User

モデルを変更した後、makemigrationsおよびmigrateコマンドを再度実行して変更を適用する必要があることに注意してください。

python manage.py makemigrations
python manage.py migrate

次の図に示すように、変更が完了した後でコマンド makemigrations を実行すると、エラーは報告されません。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/wenhao_ir/article/details/131773627