我有一个基于django-oscar
(and ) 的项目,它使用该模块django-cms
在具有不同SITE_ID
s 的多个域上运行。django.contrib.sites
该项目已经富有成效,我不能再更改类别 slug - 我希望避免将整个代码切换到嵌套集树或相邻树 - 为了您更好地理解:初始要求不想要不同的类别排序对于每个域,所以我只使用 Oscars 默认类别实现。
但是由于 Oscars 类别模型/管理器基于物化路径树实现,因此我必须考虑与通常的 Django 更改默认排序方式的一些差异django-treebeard
。
给定模型中的这两个额外字段(继承自django-oscar
s AbstractCategory)
class Category(AbstractCategory):
# ...
order_site_1 = models.IntegerField(
null=False,
default=0
)
order_site_2 = models.IntegerField(
null=False,
default=0
)
我不能简单地将排序添加到元类中,例如:
class Category(AbstractCategory):
class Meta:
ordering = ['depth', '-order_site_{}'.format(Site.objects.get_current().id), 'name']
首先,它将忽略该指令,因为treebeard
sMP_NodeManager.get_queryset()
不尊重自定义排序 - 对于 MP_Tree 逻辑,它必须依赖于插入时生成的排序(存储在 中path
),因此这种方法将违背 MP_Tree 本身的目的。
我也看过node_order_by
- 但如文档中所述:
node_order_by
启用时节点的顺序不正确。在节点插入时强制执行排序,因此如果在node_order_by
插入节点后修改了一个属性,则树排序将不一致。
但同样在具有不同类别排序的多个域上,这是没有用的。我能想到的唯一方法是覆盖MP_NodeManager
类:
class CustomOrderQuerySet(MP_NodeManager):
def get_queryset(self):
sort_key = '-order_site_{}'.format(Site.objects.get_current().id)
return MP_NodeQuerySet(self.model).order_by('depth', sort_key, 'name')
但是这种方法显然是错误的,因为 MP_Tree 依赖于path
排序来生成正确的树 - 我的想法是遍历所有条目,比较path
,忽略最后一部分并根据排序order_site_{id}
并将其重新转换为QuerySet
.
我什至不确定这是否可能,并且我想避免去那里,所以我的问题是:有没有办法在 ORM 语句链中反映这种逻辑,以便我可以继续使用本机QuerySet
?