如何解决Django:制作均匀分布的混合项目提要
假设我想生成一个由 ItemA
和 ItemB
组成的提要,每个项目都有一个“published_date”字段,较新的项目应该出现在提要的顶部。但是,我想进一步确保提要始终包含 2 个 ItemA
,然后是 1 个 ItemA
,然后是 2 个 ItemA
,....无论绝对发布日期如何(即,即使最近发布的 10 个项目都是 A,如果有实例,我仍然会将 B 视为第三个项目)。
如何在 Django 中实现这样的功能?
我最初是这样做的
# models.py
class FeedItem(models.Model):
id = HashidAutoField(primary_key=True,min_length=8,alphabet="0123456789abcdefghijklmnopqrstuvwxyz")
created = models.DateTimeField(auto_Now_add=True)
updated = models.DateTimeField(auto_Now=True,db_index=True)
# When is this scheduled to be published
publish_date = models.DateTimeField(db_index=True)
# Type of Feed Item
ITEM_TYPES = Choices((1,'A','ItemA'),(2,'B','ItemB'))
# item_type
item_type = models.PositiveSmallIntegerField(db_index=True,choices=ITEM_TYPES)
def save(self,force_insert=False,force_update=False,using=None,update_fields=None,**kwargs):
"""
Ensure that when we save each subclass then we get the correct item_type
:param force_insert:
:param force_update:
:param using:
:param update_fields:
:param kwargs:
:return:
"""
if (self.__class__.__name__ == 'FeedItemA'
and self.item_type != self.ITEM_TYPES._identifier_map['A']):
self.item_type = self.ITEM_TYPES._identifier_map['A']
elif (self.__class__.__name__ == 'FeedItemB'
and self.item_type != self.ITEM_TYPES._identifier_map['B']):
self.item_type = self.ITEM_TYPES._identifier_map['B']
class Meta:
ordering = ['-publish_date',]
class FeedItemA(FeedItem):
...
class FeedItemB(FeedItem):
...
然后是一个视图
# views.py
class FeedItemViewSet(viewsets.ReadOnlyModelViewSet):
queryset = FeedItem.objects.all()
permission_classes = ()
serialization_info = {
'ItemA': FeedSerializationInfo(FeedItemASerializer,'a','artworkFeeditema'),'ItemB': FeedSerializationInfo(FeedItemBSerializer,'b','blogpostFeeditemb'),}
filter_backends = (filters.DjangoFilterBackend,rest_filters.OrderingFilter)
ordering_fields = ['publish_date','updated']
def list(self,request,*args,**kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
data = []
for item in page:
info = self.serialization_info[item.get_item_type_display()]
related_item = getattr(item,info.related_name)
data.append(info.serializer_class(related_item,context={'request': request}).data)
return self.get_paginated_response(data)
这实现了 2 种不同类型的混合,但它们的顺序将完全由 publish_date
决定,我们没有得到 2 个 A、1 个 B 等的均匀混合...>
也许有某种方法可以通过从 A 的有序列表中弹出 2,然后从 B 中弹出 1 等直到两个列表都用完来生成新的查询集?然后将该查询集用于列表视图集?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。