首页 > 解决方案 > 当每个视图需要处理不同的模型时,如何遵循django中的DRY原则?

问题描述

我试图选择一个好的

我有几页,每页都有一个表格。我不得不为这些页面中的每一个(大约 20 个不同的页面)创建一个视图,但代码几乎是相似的。我没有看到任何减少重复代码的方法,因为不同的视图都必须处理不同的 ModelForm 实例。

示例可能是一种视图:

def portfolio_dividend_new(request, profile_id):
    profile = Profile.objects.get(id=profile_id)
    post_req = False

    if request.POST:
        form = DividendForm(request.POST)
        form.save()
        post_req = True

    form = DividendForm()
    return render(request, 'plan/portfolio/new_dividend.html',
                  {'form': form,
                   'profile': profile,
                   'post_req': post_req}
                  )

另一个视图的示例:

def portfolio_buyback_new(request, profile_id):
    profile = Profile.objects.get(id=profile_id)
    post_req = False

    if request.POST:
        form = SharebuybackForm(request.POST)
        form.save()
        post_req = True

    form = SharebuybackForm()
    return render(request, 'plan/portfolio/new_buyback.html',
                  {'form': form,
                   'profile': profile,
                   'post_req': post_req}
                  )

正如您所看到的,这些视图有很多相同的代码,但是由于它们必须实例化不同的 ModelForm 实例,所以我不知道如何防止它们变成两个视图。如果它只有两个视图,但它变成了 20 个不再可维护的视图,这不会是一个问题。

当我必须在每个视图中使用不同的模型形式时,如何避免违反 DRY 原则?我不认为 CBV 在这里有更好的解决方案,因为代码本身一点也不长而且很简单,但问题是大部分代码会重复自己。

有什么建议么 ?

标签: pythondjangodjango-formsdry

解决方案


制作差异参数并用于functools.partial部分应用它们。

from functools import partial

def portfolio_page(model, the_url, request, profile_id):
    profile = Profile.objects.get(id=profile_id)
    post_req = False

    if request.POST:
        form = model(request.POST)
        form.save()
        post_req = True

    form = model()
    return render(request, the_url,
                  {'form': form,
                   'profile': profile,
                   'post_req': post_req}
                  )

portfolio_dividend_new = partial(
    portfolio_page, DividendForm, 'plan/portfolio/new_dividend.html')

portfolio_buyback_new = partial(
    portfolio_page, SharebuybackForm, 'plan/portfolio/new_buyback.html')

或类似的东西。你只举了两个例子。您可能会发现更多相似之处,例如'plan/portfolio/{}.html'.format(the_file)它们是否都相同。或者,如果它们在更多地方不同,则可能需要更多参数。


如果你经常使用它,你甚至可以部分地使用它,比如

page = partial(partial, portfolio_page)

portfolio_dividend_new = page(DividendForm, 'new_dividend')
portfolio_buyback_new = page(SharebuybackForm, 'new_buyback')
foopage = page(FooModel, 'foo')
barpage = page(BarModel, 'bar')
# etc.

我不知道您可以将该语句中的“模型”用作变量。

类只是 Python 中的另一种对象(就像函数一样),因此您可以将它们分配给变量并将它们作为参数传递给其他函数等。


推荐阅读