У меня есть проект на основе django-oscar
(и django-cms
), который выполняется на нескольких доменах с разными SITE_ID
с использованием модуля django.contrib.sites
.Проект уже продуктивен, и я больше не могу менять слагов категорий. Также я хочу избежать переключения всего кода на деревья вложенных множеств или смежные деревья - для вашего лучшего понимания: первоначальные требования не требовали сортировки по другим категориям.для каждого домена, поэтому я просто использовал реализацию категории Oscars по умолчанию.
Но так как модель / менеджер категории Oscars основана на реализации django-treebeard
s материализованного дерева путей , я должен рассмотреть несколькоОтличия от обычного Django-способа изменения порядка по умолчанию.
Учитывая эти два дополнительных поля в модели (которая наследуется от 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
s MP_NodeManager.get_queryset()
не учитывает пользовательскую сортировку - для логики MP_Tree он должен полагаться насортировка, сгенерированная во время вставки (которая хранится в path
), так что этот подход не подействуетose самого 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
?