使用Django Abstract Class创建关系并继承该类会因某种原因创建两个反向关系

use*_*875 8 django inheritance django-models

这是我的模特:

class Post(models.Model):
    owner = models.ForeignKey(User, related_name="%(app_label)s%(class)s_set")
    post = models.CharField(max_length=400)

    class Meta:
        abstract = True


class DS(Post):
    location = models.ForeignKey(Location, blank=True, null=True, related_name="%(app_label)s%(class)s_set")

    class Meta(Post.Meta):
        abstract = True

class S(DS):
    # same as DS
    pass
Run Code Online (Sandbox Code Playgroud)

现在,当我打开Python shell并执行此操作时:

a = User.objects.get(username='a')
dir(a)
Run Code Online (Sandbox Code Playgroud)

然后这两个出现:

['myapps_set', 's_set']
Run Code Online (Sandbox Code Playgroud)

当我这样做时:

a.s_set.all()
Run Code Online (Sandbox Code Playgroud)

它返回一个S对象,但是当我这样做时:

a.myapps_set.all()
Run Code Online (Sandbox Code Playgroud)

它返回三个S对象(它返回的第一个S对象与我返回的对象相同a.s_set.all().我的两个问题是,

1)为什么即使我特意做了owner = models.ForeignKey(User, related_name="%(app_label)s%(class)s_set"),s_set也可以用用户对象访问?

2)为什么他们会返回两组不同的对象(即如何myapps_set.all()返回3(正确的答案)而s_set.all()只返回一个?

Yev*_*lev 4

我刚刚在干净的虚拟环境中使用 django==1.8 测试了您的代码,并且只得到了一种反向关系。

$ pip freeze
decorator==4.0.6
Django==1.8
ipython==4.0.1
ipython-genutils==0.1.0
path.py==8.1.2
pexpect==4.0.1
pickleshare==0.5
ptyprocess==0.5
simplegeneric==0.8.1
traitlets==4.0.0
wheel==0.24.0

$./manage.py shell
In [1]: from django.contrib.auth.models import User
In [2]: a = User.objects.all()[0]
In [3]: [item for item in sorted(dir(a)) if 'tutu' in item or item.startswith('s') and not item.startswith('_')]
Out[3]: 
['save',
 'save_base',
 'serializable_value',
 'set_password',
 'set_unusable_password',
 'tutus_set']
Run Code Online (Sandbox Code Playgroud)

这是代码:https://www.dropbox.com/s/rsej26d70swyllr/stack34406825.tar.gz ?dl=0

看起来您已经使用本地版本的 django 做了一些事情,或者您没有在此处显示所有代码。