当每个视图需要处理不同的模型时,如何在django中遵循DRY原则?
How to follow the DRY principle in django when each view needs to deal with a different model?
我试过选的不错
我有几页,每页有一张表格。我不得不为每个页面(大约 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 是更好的解决方案,因为代码本身不是很长而且很简单,但问题是很多代码都是重复的。
有什么建议吗?
创建差异参数并使用 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.
I did not know you could use the "model" in that statement as a variable.
类 只是 Python 中的另一种类型的对象(函数也是如此),因此您可以将它们分配给变量并将它们作为参数传递给其他函数等。
我试过选的不错
我有几页,每页有一张表格。我不得不为每个页面(大约 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 是更好的解决方案,因为代码本身不是很长而且很简单,但问题是很多代码都是重复的。
有什么建议吗?
创建差异参数并使用 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.
I did not know you could use the "model" in that statement as a variable.
类 只是 Python 中的另一种类型的对象(函数也是如此),因此您可以将它们分配给变量并将它们作为参数传递给其他函数等。