Django combine foreign keys in a single queryset

核能气质少年 提交于 2019-12-11 04:35:04

问题


I have a model in a Django application that is being referenced by multiple other models as a ForeignKey.

What I am looking for is for a way to create a single queryset for all objects of this class that are being referenced as ForeignKey by the rest of the classes based on some criteria.

I am not even sure if this is possible, but I thought about asking anyway.

class Person(models.Model):
    pass


class Book(models.Model):
    year_published = models.PositiveIntegerField()
    author = models.ForeignKey(Person)


class MusicAlbum(models.Model):
    year_published = models.PositiveIntegerField()
    producer = models.ForeignKey(Person)

recent_books = Book.objects.filter(year_published__gte=2018)
recent_music_albums = MusicAlbum.objects.filter(year_published__gte=2018)

# How can I create a **single** queryset of the Person objects that are being referenced as `author` in `recent_books` and as `producer` in `recent_music_albums`?

Thanks for your time.


回答1:


I don't have Django in front of me at the moment, but what about something like:

class Person(models.Model):
    pass


class Book(models.Model):
    year_published = models.PositiveIntegerField()
    author = models.ForeignKey(Person, related_name='books')


class MusicAlbum(models.Model):
    year_published = models.PositiveIntegerField()
    producer = models.ForeignKey(Person, related_name='albums')

Person.objects.filter(books__year_published__gte=2018, albums__year_published__gte=2018)

Or, if you have to do those first two queries anyway,

Person.objects.filter(books__in=recent_books, albums__in=recent_music_albums)



回答2:


You will have on Person model instances a RelatedManager for Books and MusicAlbums. Probably they will still have the default names book_set and musicalbum_set since you didn't override them.

You can use these to find the books/music albums associated with one person instance:

persons_books = person.book_set.all()
persons_musicalbums = person.musicalbum_set.all()

And similarly you can generate the relevant queryset from the model manager:

qs = Person.objects.exclude(book=None).exclude(musicalbum=None)



回答3:


Same can be achieved by this :

person = Person.objects.latest('book__year_published', 'musicalbum__year_published')

or

personList = Person.objects.all().order_by('-book__year_published', '-musicalbum__year_published')



来源:https://stackoverflow.com/questions/49241246/django-combine-foreign-keys-in-a-single-queryset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!