将多个(不同的)queryset链接在一起,将它们视为单个queryset。
django-querysetsequence的Python项目详细描述
QuerySetSequence包装器有助于处理不同的QuerySet 类,而将它们视为单个QuerySet。
支持的功能
下面列出了django的^{tt4}$特性,即QuerySetSequence 工具。行为应该与QuerySet的行为匹配,但应用于 多个QuerySets:
- 获取字段列表的方法(例如filter(),exclude(), get(),order_by())必须使用所有 分-QuerySets。
- 相关模型之间的关系可以工作(例如'foo__bar','foo',或者 'foo_id')。语法)。
- sub-QuerySets的计算时间越晚越好(例如,在 迭代,切片,酸洗,repr()/len()/list()/bool() 电话)。
- 未经测试/未实现的公共QuerySetapi方法引发 NotImplementedError。
QuerySetapi由QuerySetSequence
实现Method | Implemented? | Notes |
---|---|---|
^{tt8}$ | ✓ | See [1] for information on the ^{tt2}$ lookup: ^{tt28}$. |
^{tt9}$ | ✓ | See [1] for information on the ^{tt2}$ lookup: ^{tt28}$. |
^{tt32}$ | ✓ | |
^{tt11}$ | ✓ | Does not support random ordering (e.g. ^{tt34}$). See [1] for information on the ^{tt2}$ lookup: ^{tt28}$. |
^{tt37}$ | ✓ | |
^{tt38}$ | ✗ | |
^{tt39}$ | ✗ | |
^{tt40}$ | ✗ | |
^{tt41}$ | ✗ | |
^{tt42}$ | ✗ | |
^{tt43}$ | ✓ | |
^{tt44}$ | ✓ | |
^{tt45}$ | ✗ | |
^{tt46}$ | ✗ | |
^{tt47}$ | ✗ | |
^{tt48}$ | ✓ | |
^{tt49}$ | ✓ | |
^{tt50}$ | ✓ | |
^{tt51}$ | ✓ | |
^{tt52}$ | ✓ | |
^{tt53}$ | ✓ | |
^{tt54}$ | ✗ | |
^{tt55}$ | ✗ |
Operator | Implemented? | Notes |
---|---|---|
AND (^{tt57}$) | ✓ | A ^{tt1}$ can be combined with a ^{tt2}$. The ^{tt4}$ in the ^{tt1}$ are filtered to ones matching the same ^{tt62}$. Each of those is ANDed with the other ^{tt2}$. |
OR (^{tt64}$) | ✓ | A ^{tt1}$ can be combined with a ^{tt2}$ or ^{tt1}$. When combining with a ^{tt2}$, it is added to the ^{tt1}$. Combiningg with another ^{tt1}$ adds together the two underlying sets of ^{tt4}$. |
Method | Implemented? | Notes |
---|---|---|
^{tt10}$ | ✓ | See [1] for information on the ^{tt2}$ lookup: ^{tt28}$. |
^{tt76}$ | ✗ | Cannot be implemented in ^{tt1}$. |
^{tt78}$ | ✗ | Cannot be implemented in ^{tt1}$. |
^{tt80}$ | ✗ | Cannot be implemented in ^{tt1}$. |
^{tt82}$ | ✗ | Cannot be implemented in ^{tt1}$. |
^{tt84}$ | ✓ | |
^{tt85}$ | ✗ | Cannot be implemented in ^{tt1}$. |
^{tt87}$ | ✓ | |
^{tt88}$ | ✓ | If no fields are given, ^{tt89}$ on each model is required to be identical. |
^{tt90}$ | ✓ | See the docuemntation for ^{tt88}$. |
^{tt92}$ | ✓ | If no ordering is set this is essentially the same as calling ^{tt92}$ on the first ^{tt2}$, if there is an ordering, the result of ^{tt92}$ for each ^{tt2}$ is compared and the “first” value is returned. |
^{tt97}$ | ✓ | See the documentation for ^{tt92}$. |
^{tt99}$ | ✗ | |
^{tt100}$ | ✓ | |
^{tt101}$ | ✓ | |
^{tt102}$ | ✓ | |
^{tt103}$ | ✓ | |
^{tt104}$ | ✓ | Only available on Django >= 2.1. |
Method | Notes |
---|---|
^{tt106}$ | Returns the list of ^{tt2}$ objects that comprise the sequence. Note, if any methods have been called which modify the ^{tt1}$, the ^{tt2}$ objects returned by this method will be similarly modified. The order of the ^{tt2}$ objects within the list is not guaranteed. |
[1] | (1, 2, 3, 4) ^{tt1}$ supports a special field lookup that looks up the index of the ^{tt2}$, this is represented by ^{tt28}$. This can be used in any of the operations that normally take field lookups (i.e. ^{tt8}$, ^{tt9}$, and ^{tt10}$), as well as ^{tt11}$. A few examples are below: ^{pr 1}$Note Ordering first by ^{tt2}$ allows for a more optimized code path when iterating over the entries. Warning Not all lookups are supported when using ^{tt28}$ (some lookups simply don’t make sense; others are just not supported). The following are allowed:
|
要求
- Python(2.7、3.5、3.6、3.7)
- Django(1.11、2.0、2.1、2.2)
- (可选)Django REST Framework(3.6.3+,3.7,3.8,3.9)
安装
使用pip安装包。
pip install --upgrade django-querysetsequence
用法
# Import QuerySetSequencefromqueryset_sequenceimportQuerySetSequence# Create QuerySets you want to chain.from.modelsimportSomeModel,OtherModel# Chain them together.query=QuerySetSequence(SomeModel.objects.all(),OtherModel.objects.all())# Use query as if it were a QuerySet! E.g. in a ListView.
示例
classAuthor(models.Model):name=models.CharField(max_length=50)classMeta:ordering=['name']def__str__(self):returnself.nameclassArticle(models.Model):title=models.CharField(max_length=100)author=models.ForeignKey(Author)def__str__(self):return"%s by %s"%(self.title,self.author)classBook(models.Model):title=models.CharField(max_length=50)author=models.ForeignKey(Author)release=models.DateField(auto_now_add=True)def__str__(self):return"%s by %s"%(self.title,self.author)# Create some data.alice=Author.objects.create(name='Alice')article=Article.objects.create(title='Dancing with Django',author=alice)bob=Author.objects.create(name='Bob')article=Article.objects.create(title='Django-isms',author=bob)article=Book.objects.create(title='Biography',author=bob)# Create some QuerySets.books=Book.objects.all()articles=Article.objects.all()# Combine them into a single iterable.published_works=QuerySetSequence(books,articles)# Find Bob's titles.bob_works=published_works.filter(author=bob)# Still an iterable.print([w.titleforwinbob_works])# prints: ['Biography', 'Django-isms']# Alphabetize the QuerySet.published_works=published_works.order_by('title')print([w.titleforwinpublished_works])# prints ['Biography', 'Dancing with Django', 'Django-isms']
django rest框架集成
django querysetsequence附带了一个定制的CursorPagination类 帮助与django rest框架集成。它被优化为在 QuerySetSequence先按QuerySet,然后按正常值ordering 配置。这将使用优化的代码路径进行迭代,以避免 交错单个QuerySets。例如:
fromqueryset_sequence.paginationimportSequenceCursorPaginationclassPublicationPagination(SequenceCursorPagination):ordering=['author','title']classPublicationViewSet(viewsets.ModelViewSet):pagination_class=PublicationPaginationdefget_queryset(self):# This will return all Books first, then all Articles. Each of those# is individually ordered by ``author``, then ``title``.returnQuerySetSequence(Book.objects.all(),Article.objects.all())
归因
这是根据一些django片段编写的:
贡献
- 检查是否有未解决的问题或打开新的问题以围绕 特征想法或缺陷。
- 从github上的存储库开始进行更改。
- 编写一个测试,显示bug已被修复或该特性的工作方式 预期。
- 发送一个pull请求并对维护程序进行bug操作,直到它被合并并发布。