如何在Python和Django中重用代码

时间:2015-03-18 11:04:28

标签: python django dry

我有一个适用于Django的工作版本/归档系统,它存在于多个视图中。但是,我想在努力遵守DRY原则的同时重写这一点。

当前代码

def archive_calc(self, rev_num, primary_field):
    model_a = InstrumentAnnual.objects.get(instrument_details_id = primary_field, revision_number = rev_num)
    model_b = InstrumentAnnualArchive()

    object_list_annual = model_a.instrumentperiodicreview_set.filter(instrument_annual__instrument_details = primary_field)
    object_list_ageing = model_a.instrumentequipmentitem_set.filter(instrument_annual__instrument_details = primary_field)

    for obj in object_list_annual:
        obj.instrument_annual_id = self.object.id
        obj.save()
    for obj in object_list_ageing:
        obj.instrument_annual_id = self.object.id
        obj.save()

    for field in model_a._meta.fields:
        setattr(model_b, field.name, getattr(model_a, field.name))
    model_b.pk = None
    model_b.current_revision = False
    model_b.save()

    model_a.delete()

这部分代码传递了转号和主键,并使用这些对象归档记录

潜在解决方案

我已经做了很多阅读/ Youtube观看,并且我不太确定最佳路径。我是否应该在视图(新创建的应用程序)中创建一个具有以下类似内容的新应用程序,然后将代码导入所需的视图?

def archive_calc(self, rev_num, primary_field, type):
    if type == "instrument":
        model_a = InstrumentAnnual.objects.get(instrument_annual_id = primary_field, revision_number = rev_num)
        model_b = InstrumentAnnualArchive()

        object_list_annual = model_a.instrumentperiodicreview_set.filter(instrument_annual__instrument_details = primary_field)
        object_list_ageing = model_a.instrumentequipmentitem_set.filter(instrument_annual__instrument_details = primary_field)

        for obj in object_list_annual:
            obj.instrument_annual_id = self.object.id
            obj.save()
        for obj in object_list_ageing:
            obj.instrument_annual_id = self.object.id
            obj.save()

    elif type == "time":
        model_a = Time.objects.get(time_id = primary_field, revision_number = rev_num)
        model_b = TimeArchive()
        etc etc....

    for field in model_a._meta.fields:
        setattr(model_b, field.name, getattr(model_a, field.name))
    model_b.pk = None
    model_b.current_revision = False
    model_b.save()

    model_a.delete()

然后创建' archive_calc'的实例。在我需要使用归档代码的任何视图中使用这样的东西?

from resusablecode.views import archive_calc

class InstrumentCreateView(SuccessMessageMixin, UpdateView):
    (normal view code...)

    archiveinstance = archive_calc()
    archiveinstance(rev_num, primary_field, type)

这会起作用吗?或者我是否会离开?

或者,考虑到每个视图中的差异数量,最好坚持使用当前设置吗?

提前致谢并澄清我使用的是基于类的观点,如果这与此事有任何关系。

1 个答案:

答案 0 :(得分:0)

从您的视图中移动尽可能多的逻辑到您的模型类。遵循建议"瘦视图,胖模型"。

我可以向你推荐这本书" Django的两个勺子"最佳实践。

示例:

class InstrumentAnnual(models.Model):
    ...
    def archive_calc(self, rev_num):
        archive = InstrumentAnnualArchive()
        list_annual = self.instrumentperiodicreview_set.filter(...)
        ...