我有一个基于django-oscar(and ) 的项目,它使用该模块django-cms在具有不同SITE_IDs 的多个域上运行。django.contrib.sites该项目已经富有成效,我不能再更改类别 slug - 我希望避免将整个代码切换到嵌套集树或相邻树 - 为了您更好地理解:初始要求不想要不同的类别排序对于每个域,所以我只使用 Oscars 默认类别实现。
但是由于 Oscars 类别模型/管理器基于物化路径树实现,因此我必须考虑与通常的 Django 更改默认排序方式的一些差异django-treebeard。
给定模型中的这两个额外字段(继承自django-oscars 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']
首先,它将忽略该指令,因为treebeardsMP_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?