Django makemigrations 在多对多关系上出错

问题描述

我想要的:

存储一群人的跑步信息。

我做了什么:

from django.db import models
from django.contrib.auth.models import User
from datetime import timedelta


class Route(models.Model):
    name = models.CharField(max_length=50)


class Run(models.Model):
    date = models.DateField()
    type = models.ForeignKey(Route,on_delete=models.PROTECT)
    runners = models.ManyToManyField(User,through='RunnerResult',through_fields=["user","run"])


class RunnerResult(models.Model):
    user = models.ForeignKey(User,on_delete=models.PROTECT)
    run = models.ForeignKey('Run',on_delete=models.PROTECT)
    result = models.DurationField(default=timedelta())

问题:

当我执行 makemigrations 时,出现以下错误

SystemCheckerror: System check identified some issues:

ERRORS:
run.Run.runners: (fields.E339) 'RunnerResult.run' is not a foreign key to 'User'.
        HINT: Did you mean one of the following foreign keys to 'User': user?
run.Run.runners: (fields.E339) 'RunnerResult.user' is not a foreign key to 'Run'.
        HINT: Did you mean one of the following foreign keys to 'Run': run?

尝试在彼此和其他一些操作之间交换 through_fields 和模型。我开始想起我对 M2M 关系的误解。

解决方法

您以错误的顺序指定了 through_fields。您首先应该指定引用 source 的关系,然后是 target 的关系,因此:

class Run(models.Model):
    date = models.DateField()
    type = models.ForeignKey(Route,on_delete=models.PROTECT)
    runners = models.ManyToManyField(
        User,through='RunnerResult',through_fields=('run','user')
    )

因为只有一个 ForeignKeyRun,一个到 User,所以您不需要指定 through_fields=… parameter [Django-doc]。因此,您可以将其实现为:

class Run(models.Model):
    date = models.DateField()
    type = models.ForeignKey(Route,through='RunnerResult'
        # no through_fields
    )

注意:通常使用 settings.AUTH_USER_MODEL [Django-doc] 来引用用户模型比直接使用 User model [Django-doc] 更好。有关详细信息,您可以查看 referencing the User model section of the documentation