【问题标题】:What's the correct way to use helpers to extend functionality in Django models?在 Django 模型中使用帮助器扩展功能的正确方法是什么?
【发布时间】:2022-01-16 21:22:50
【问题描述】:

我在 Django 中为我的模型添加了一些扩展功能。为了不重载模型根接口(和文件),我使用了一些帮助器作为模型的属性。

我想要的是将方法和属性分组到这个助手中,我想要的是这样的:

class Product(models.Model):
    downloads = DownloadsHelper()
    # ....
    pass

p = Product.objects.first()
p.downloads.files_count(p)
p.downloads.reset_permissions(p)
# ...

为了不必每次都将实例传递给助手,我可以使用另一种方法。

class Product(models.Model):
    def __init__(self, *args, **kwargs):
        super(Product, self).__init__(*args, **kwargs)
        self.downloads = DownloadsHelper(self)
        self.shipping = ShippingHelper(self)

p = Product.objects.first()
p.downloads.files_count
p.downloads.reset_permissions()

最后,一个更通用/概念化的方式来做这些事情是这样的:


class Helper:
    def __init__(self, helped):
        self.helped = helped

class Helper1(Helper):
    attribute_name = 'helloing'

    def hola(self): print("hola")


class Helper2(Helper):
    attribute_name = 'goodbying'

    def chau(self): print("chau")


class Helped:
    def __init__(self):
        self._install_helpers()

    def _install_helpers(self):
        for helper in self.helpers:
            setattr(self, helper.attribute_name, helper(self))

class MyHelped(Helped):
    helpers = [Helper1, Helper2]

h = MyHelped()
h.helloing.hola()
h.goodbying.chau()

问题是:从 pythonic-OOP 和“Djangoid”的角度来看,这最后一种方法是正确的方法/良好的做法吗?这有什么问题吗?

感谢阅读!

【问题讨论】:

  • 您描述的第一种方法在我看来是最清晰/可维护的。这样,每个使用代码的人都可以快速知道您的模型具有哪些属性/帮助器。最后一种方式有点混乱,没有明确快速的方法来检查函数调用哪个属性
  • 感谢您的回答。好的,好点。也许我可以使用元组列表或字典来分配帮助类的属性名称。我同意这有点神奇,但我不想在我使用此功能的每个模型中重复 __init__() 覆盖

标签: python django oop django-models helper


【解决方案1】:

也许您没有展示您的方法的全部复杂性,但从您展示的内容来看,它可以简化一点。

您可以使用“直接/简单”继承,如果您有很多方法,那么为了组织,您可以在方法名称前加上 h1_h2_ 以指示它们来自哪个帮助器类:

from django.db import models

class Helper1:
    def h1_hola(self):
        print("hola")

class Helper2:
    def h2_chau(self):
        print("chau")

class MyHelped(Helper1, Helper2, models.Model):
    pass

h = MyHelped()
h.h1_hola()
h.h2_chau()

这种更简单的方法是否足以满足您的特定需求?

【讨论】:

  • 感谢您的回答。问题是,使用这种方法,您需要在每个方法中添加 hX_ 前缀,并且它扩展了 MyHelped 根接口。我知道 "flat is better than nested" 但在这种情况下,我更喜欢嵌套的 one 解决方案,以避免在方法等中使用前缀。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2018-05-07
  • 2013-11-22
  • 1970-01-01
  • 2022-01-03
  • 2020-08-18
相关资源
最近更新 更多