【问题标题】:How to enable function to render templates based on try, except blocks from within another view in Django?如何启用基于try渲染模板的功能,除了Django中另一个视图中的块?
【发布时间】:2017-11-28 04:51:56
【问题描述】:

我正在 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 for the return render(request , 模板) 部分。

为了更好地解释我自己,try/except 块成功捕获了异常,但是它不返回块中指定的模板,而是返回视图并呈现我在视图中的模板。

我尝试了什么?如果我将 guest_constraint (vendor.py) 的代码放在 index (views.py) 中,我认为没有问题并且可以按预期工作。然而,这并不能很好地扩展,因为我希望在 views.py 中为许多不同的函数调用 guest_contraint

我对编程和 Django 还很陌生,我还有很多东西要学。如果你能告诉我你认为我做错了什么,或者关于 Django(甚至是基本的 Python)的什么主题可以帮助我解决这个问题,我将不胜感激。谢谢!

编辑:我忘了说,我使用的是 Django 1.11.6。
编辑 2: 哎呀,我忘了包括我如何在我的索引视图中使用该功能。我的错,对不起。

解决方案:

感谢 @cwallenpoole 以及我对他的回复所做的一些更改,我能够编辑我的代码来做我想做的事情,现在看起来像这样:

供应商.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')

【问题讨论】:

  • 我没有看到您的 index 视图中使用的 guest_constraint 方法。
  • 抱歉,我不小心遗漏了如何在 views.py 函数中使用该函数。现在已经更正了。

标签: python django django-templates django-views django-middleware


【解决方案1】:

看来您可能需要考虑使用注释而不是仅仅作为函数:

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

这意味着您需要确保带注释的视图采用 guest 和 room_info 参数,但这也意味着您定义了一次变量。

【讨论】:

  • 您好,非常感谢您的回复。我试图实现它,我觉得这就是我想要的方式。我不知何故有一个错误。似乎当请求通过所有这些过滤器时(因为用户有资格这样做)Django 抛出一个 NoneType 异常。您是否知道 guest_constraint 注释将流程返回到 views.py 函数的方法,这样只要来宾通过这些约束,我就可以呈现我喜欢的模板?考虑到我真的很想在我的所有视图中使用这个注释。
  • 忽略上面的消息。我能够在需要编辑的地方编辑代码。感谢您抽出宝贵时间回答这个问题。
【解决方案2】:

您的示例views.py 没有使用guest_constraint 显示任何内容,只是导入。听起来你想要在索引(和其他视图)中间有一些东西来检查 guest_constraint。处理它的一种简单方法是返回两个值 - 结果状态和 render() 结果。将False 添加到每个现有的return render() 行,并在函数末尾返回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

【讨论】:

  • 感谢这位朋友。我决定选择使用与注释相同的其他响应。
猜你喜欢
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 2013-04-26
  • 2014-01-15
相关资源
最近更新 更多