如何启用函数以基于尝试呈现模板,除了 Django 中另一个视图中的块?
How to enable function to render templates based on try, except blocks from within another view in Django?
我正在 Django 中创建一个应用程序,允许我的用户根据已存储在数据库中的信息从我的站点订购商品。
并非我的所有用户都应该能够订购某些商品,为此我编写了一个带有比较语句的管道并尝试,块除外。
一小段可重现的代码如下所示:
vendor.py
def guest_constraint(request)
# Ensure user in request is a house-guest by checking if it has an active token.
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
# Check for Hotel Room Information linked to Guest Token
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
views.py
from .vendor import guest_constraint
@login_required
def index(request):
guest_contraint(request) # Filter out users with no access to this process.
user = request.user # Grab user defined in request.
name = user.get_short_name() # Grab first name of user.
return render(request, 'extGuest/appGuestFlow/choose_order_type.html')
挑战: 我可以成功地将这个小脚本导入到我的视图中,我可以看到它的内容是 运行 except对于 return render(request, template) 部分。
为了更好地解释自己,try/except 块成功捕获了异常,但是它没有 return 块中指定的模板,而是返回到视图并呈现模板我有在看。
我尝试了什么? 如果我将 guest_constraint (vendor.py) 的代码放在索引 (views.py) 中我看不出问题并且按预期工作。然而,这并不能很好地扩展,因为我希望为 views.py
中的许多不同函数调用 guest_contraint
我对编程和 Django 还很陌生,但我还有很多东西要学。如果你能给我一个提示,告诉我你认为我做错了什么,或者 Django 上的什么主题(甚至是基本 Python)可以帮助我解决这个问题,我将不胜感激。谢谢!
编辑: 忘了说了,我用的是 Django 1.11.6.
编辑 2: 哎呀,我忘了在我的索引视图中包含我如何使用该函数。我的错,对不起。
解决方案:
感谢 @cwallenpoole 以及我对他的回复所做的一些更改,我能够编辑我的代码来完成我想做的事情,它现在看起来像这样:
vendor.py |已更新
def guest_constraint(function):
def _inner_guest_constraint(request)
# This part should be familiar
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
# Once all checks are passed return flow back to function.
return function(request)
# return the wrapping
return _inner_guest_constraint
views.py |已更新
from .vendor import guest_constraint
@login_required
@guest_constraint
def index(request):
user = request.user # Grab user defined in request.
name = user.get_short_name() # Grab first name of user.
return render(request, 'extGuest/appGuestFlow/choose_order_type.html')
看来您可能想考虑使用注释而不是仅仅作为一个函数:
def guest_constraint(fn):
def _inner_guest_constraint(request)
# This part should be familiar
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
# Call the wrapped function
fn(request)
# return the wrapping
return _inner_guest_constraint
然后你可以简单地注释:
@login_required
@guest_constraint
def index(request):
您还可以修改它,以便您的包装函数添加参数:
def guest_constraint(fn):
def _inner_guest_constraint(*args,**kwargs):
# stuff
kwargs.update({'guest':guest, 'room_info': room_information})
fn(*args,**kwargs)
return _inner_guest_constraint
这意味着您需要确保带注释的视图采用来宾和 room_info 参数,但这也意味着您只定义一次变量。
您的示例 views.py 没有使用 guest_constraint 显示任何内容,只是导入。听起来你想要索引(和其他视图)中间的东西来检查 guest_constraint。一种简单的处理方法是 return 两个值——结果状态和 render() 结果。将 False
添加到每个现有的 return render()
行和函数 return True, None
的末尾。完整功能变为:
def guest_constraint(request)
# Ensure user in request is a house-guest by checking if it has an active token.
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return False, render(request, 'extGuest/appGuestError/not_hotel_login.html')
# Check for Hotel Room Information linked to Guest Token
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return False, render(request, 'extGuest/appGuestError/constraint_error.html')
# Everything is good
return True, None
在 views.py 中你可以:
constraint_ok, constraint_render = guest_constraint(request)
if not constraint_ok:
return constraint_render
我正在 Django 中创建一个应用程序,允许我的用户根据已存储在数据库中的信息从我的站点订购商品。
并非我的所有用户都应该能够订购某些商品,为此我编写了一个带有比较语句的管道并尝试,块除外。
一小段可重现的代码如下所示:
vendor.py
def guest_constraint(request)
# Ensure user in request is a house-guest by checking if it has an active token.
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
# Check for Hotel Room Information linked to Guest Token
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
views.py
from .vendor import guest_constraint
@login_required
def index(request):
guest_contraint(request) # Filter out users with no access to this process.
user = request.user # Grab user defined in request.
name = user.get_short_name() # Grab first name of user.
return render(request, 'extGuest/appGuestFlow/choose_order_type.html')
挑战: 我可以成功地将这个小脚本导入到我的视图中,我可以看到它的内容是 运行 except对于 return render(request, template) 部分。
为了更好地解释自己,try/except 块成功捕获了异常,但是它没有 return 块中指定的模板,而是返回到视图并呈现模板我有在看。
我尝试了什么? 如果我将 guest_constraint (vendor.py) 的代码放在索引 (views.py) 中我看不出问题并且按预期工作。然而,这并不能很好地扩展,因为我希望为 views.py
中的许多不同函数调用 guest_contraint我对编程和 Django 还很陌生,但我还有很多东西要学。如果你能给我一个提示,告诉我你认为我做错了什么,或者 Django 上的什么主题(甚至是基本 Python)可以帮助我解决这个问题,我将不胜感激。谢谢!
编辑: 忘了说了,我用的是 Django 1.11.6.
编辑 2: 哎呀,我忘了在我的索引视图中包含我如何使用该函数。我的错,对不起。
解决方案:
感谢 @cwallenpoole 以及我对他的回复所做的一些更改,我能够编辑我的代码来完成我想做的事情,它现在看起来像这样:
vendor.py |已更新
def guest_constraint(function):
def _inner_guest_constraint(request)
# This part should be familiar
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
# Once all checks are passed return flow back to function.
return function(request)
# return the wrapping
return _inner_guest_constraint
views.py |已更新
from .vendor import guest_constraint
@login_required
@guest_constraint
def index(request):
user = request.user # Grab user defined in request.
name = user.get_short_name() # Grab first name of user.
return render(request, 'extGuest/appGuestFlow/choose_order_type.html')
看来您可能想考虑使用注释而不是仅仅作为一个函数:
def guest_constraint(fn):
def _inner_guest_constraint(request)
# This part should be familiar
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/not_hotel_login.html')
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return render(request, 'extGuest/appGuestError/constraint_error.html')
# Call the wrapped function
fn(request)
# return the wrapping
return _inner_guest_constraint
然后你可以简单地注释:
@login_required
@guest_constraint
def index(request):
您还可以修改它,以便您的包装函数添加参数:
def guest_constraint(fn):
def _inner_guest_constraint(*args,**kwargs):
# stuff
kwargs.update({'guest':guest, 'room_info': room_information})
fn(*args,**kwargs)
return _inner_guest_constraint
这意味着您需要确保带注释的视图采用来宾和 room_info 参数,但这也意味着您只定义一次变量。
您的示例 views.py 没有使用 guest_constraint 显示任何内容,只是导入。听起来你想要索引(和其他视图)中间的东西来检查 guest_constraint。一种简单的处理方法是 return 两个值——结果状态和 render() 结果。将 False
添加到每个现有的 return render()
行和函数 return True, None
的末尾。完整功能变为:
def guest_constraint(request)
# Ensure user in request is a house-guest by checking if it has an active token.
try:
guest = GuestProfile.objects.get(user=request.user.id)
except ObjectDoesNotExist:
return False, render(request, 'extGuest/appGuestError/not_hotel_login.html')
# Check for Hotel Room Information linked to Guest Token
try:
room_information = RoomInformation.objects.get(guest_token=guest.token)
except ObjectDoesNotExist:
return False, render(request, 'extGuest/appGuestError/constraint_error.html')
# Everything is good
return True, None
在 views.py 中你可以:
constraint_ok, constraint_render = guest_constraint(request)
if not constraint_ok:
return constraint_render