用于重定向的 Django 自定义装饰器
Posted
技术标签:
【中文标题】用于重定向的 Django 自定义装饰器【英文标题】:Django custom decorator for redirections 【发布时间】:2021-11-25 17:05:18 【问题描述】:我正在 Django 中部署一个多域平台,其中包含一些用于在网站之间执行重定向的模型逻辑。
由于重定向映射会变得有点庞大,我宁愿装饰每个视图,而不是在每个视图中复制用于重定向的代码(对于这个项目,我坚持使用基于函数的视图)。由于逻辑也可能会更改,因此我需要将所有内容集中在一个地方,并且我真的很想为此使用自定义装饰器。
我一直在尝试不同的语法来定义装饰器,但遇到了各种各样的问题。 https://pythonbasics.org/decorators/ 我正在使用我在这里看到的语法,但一开始我无法将它应用于 Django 视图。我正在使用 Django 3.2。这是与我的情况最相似的线程,它帮助我更接近我想要的结果Django custom decorator redirect problem 但是我的装饰器视图仍然返回 None 而不是 HttpResponse 对象,我不明白。
装饰器 1
def inner(request, *args, **kwargs):
print("DEBUGGING")
if settings.DEBUG == False or request.user.is_superuser == False:
return render(request, 'myapp/manutenzione.html')
func(request, *args, **kwargs)
return inner
装饰器 2 用于我的重定向
def reindirizzamenti_necessari(func):
def inner(request, *args, **kwargs):
print("REINDIRIZZAMENTI")
sito = get_current_site(request)
dominio = sito.domain
if dominio[0:4] == "www.":
dominio = dominio.split("www.")[1]
try:
dominio = Dominio.objects.get(dominio = dominio)
sito_generale = False
# Redirect to the main domain
if not dominio.principale:
redirect_necessario = True
url = '/redirect/' + dominio.città.nome.lower()
return redirect(url)
context['luogo'] = dominio.città
except:
print("DOMINIO GENERALE")
if dominio.endswith(".it"):
return redirect("https://www.mymaindomainname.com") #not using this now, just moving forward to func()
func(request, *args, **kwargs) # <---- I THINK THIS IS WHAT IS NOT WORKING (from checking the prints, I get this last one)
return inner
我的装饰视图
@debugging
@reindirizzamenti_necessari
def homepage(request):
context =
return render(request, 'myapp/index.html', context)
我当前的重定向视图
def redirect_domain(request, city):
città_url = City.objects.get(nome = city)
dominio_principale_città = Dominio.objects.get(città = città_url, principale = True)
url_finale = "https://" + dominio_principale_città.dominio
return redirect(url_finale)
当我现在调用“主页”视图时,我得到了
ValueError at /my-path
The view myapp.views.inner didn't return an HttpResponse object. It returned None instead.
【问题讨论】:
您需要从装饰器中的inner
函数返回响应,返回视图在基本情况下返回的内容,否则您只是调用视图而不对响应执行任何操作:@ 987654329@
谢谢你,看来这是我错过的最后一点!
【参考方案1】:
在我看来,你应该使用中间件而不是装饰器。
https://docs.djangoproject.com/en/3.2/topics/http/middleware/#process-view
【讨论】:
我考虑过这个选项,但我需要基于每个视图应用重定向,所以我认为装饰器方法确实是正确的以上是关于用于重定向的 Django 自定义装饰器的主要内容,如果未能解决你的问题,请参考以下文章