最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

django - Filter one-way by self-referential ManyToManyField - Stack Overflow

programmeradmin0浏览0评论

I have a model with a self-referential ManyToManyField:

class Release(models.Model):
    # ...
    bundled_releases = models.ManyToManyField("self", blank=True)

    def get_bundles(self):
        return Release.objects.filter(bundled_releases__in=[self.id])

I want get_bundles to only return releases that have self in their bundled_releases fields, but this way it also returns releases in self's bundled_releases field. How do I do this?

Edit: and vice versa I need an alternative to release.bundled_releases.all that returns the release's bundled_releases but doesn't return releases that include the release in their own bundled_releases.

I have a model with a self-referential ManyToManyField:

class Release(models.Model):
    # ...
    bundled_releases = models.ManyToManyField("self", blank=True)

    def get_bundles(self):
        return Release.objects.filter(bundled_releases__in=[self.id])

I want get_bundles to only return releases that have self in their bundled_releases fields, but this way it also returns releases in self's bundled_releases field. How do I do this?

Edit: and vice versa I need an alternative to release.bundled_releases.all that returns the release's bundled_releases but doesn't return releases that include the release in their own bundled_releases.

Share Improve this question edited Feb 2 at 4:02 bur asked Feb 2 at 0:57 burbur 7686 silver badges22 bronze badges 1
  • 1 Your relation is symmetrical, that is the problem. – willeM_ Van Onsem Commented Feb 2 at 10:20
Add a comment  | 

1 Answer 1

Reset to default 1

Your relation is symmetrical, that is the problem. By default relations to itself have symmetrical=True [Django-doc]. So that means that my_a.bundled_releases.all() is the same as my_a.release_set.all().

You thus work with:

class Release(models.Model):
    # …
    bundled_releases = models.ManyToManyField(
        'self', symmetrical=False, related_name='bundles', blank=True
    )

There is no need to make a .get_bundles(…) method however. Django makes relations accessible in two directions. Here you can trigger the relation in reverse with:

my_release.bundles.all()

This because of the related_name='bundles'.

发布评论

评论列表(0)

  1. 暂无评论