Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a relationship using a Django Abstract Class and inheriting that class creates two reverse relationships for some reason

This is my model:

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

Now, when I open up Python shell and do this:

a = User.objects.get(username='a')
dir(a)

Then these two appear:

['myapps_set', 's_set']

and when I do:

a.s_set.all()

it returns one S object, but when when I do:

a.myapps_set.all()

it returns three S objects (the first S object it returns is the same one which was returned when I do a.s_set.all(). My two questions are,

1) how come even when I specifically did owner = models.ForeignKey(User, related_name="%(app_label)s%(class)s_set"), a s_set is able to be accessed with a user object?

2) how come they return two different sets of objects (i.e. how come myapps_set.all() returns 3 (the correct answer) while s_set.all() only returns one?

like image 883
SilentDev Avatar asked Dec 22 '15 00:12

SilentDev


1 Answers

I've just tested you code with django==1.8 on clean virtual environment and got only one reverse relationship.

$ 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']

Here is the code: https://www.dropbox.com/s/rsej26d70swyllr/stack34406825.tar.gz?dl=0

It looks like you've done something with your local version of django or you've shown not all code here.

like image 81
Yevgeniy Shchemelev Avatar answered Oct 11 '22 02:10

Yevgeniy Shchemelev