如何重写 mongoengine 的 QuerySet 方法?

How to override mongoengine's QuerySet method?

如何覆盖 mongoengine 的查询集方法?

具体来说,我想覆盖 .order_by(),但我能得到的最接近的方法是添加另一个方法 ordered,它会有条件地调用 .order_by():

class TransactionQuerySet(QuerySet):

    def ordered(self, *args, target_data=None, **kwargs):
        if target_data is None:
            result = self.order_by(*args, **kwargs)
            return result
        else:
            return 'transactions sorted by target data'

理想情况下,我希望这个新方法的命名与 mongoengine 的方法相同 - order_by - 但如果我这样做,当查询集管理器被调用为 Transaction.objects.order_by 时,我将超过递归深度。

我该怎么做?

为避免递归,您应该调用父 class 的 order_by 方法。 TransactionQuerySet 应如下所示。

class TransactionQuerySet(QuerySet):

    def order_by(self, *args, target_data=None):
        if target_data is None:
            return super().order_by(*args)
        return "transactions sorted by target data"

现在,如果您在 TransactionQuerySet 对象上调用 order_by,它不会落入递归。

class Transaction(Document):
    title = StringField(max_length=100, required=True)
    last_modified = DateTimeField(default=datetime.utcnow)
    
    def __str__(self):
        return self.title

    meta = {"collection": "transaction_collection"}


with MongoClient("mongodb://localhost:27017") as client:
    connection = client.get_database("transaction")
    collection = connection.transaction_collection
    transaction_set = TransactionQuerySet(Transaction, collection)

    print(transaction_set.order_by("-title"))

输出

[<Transaction: ETHUSTD>, <Transaction: BTCUSTD>, ...]