gpt4 book ai didi

django - 在没有太多复制/粘贴的情况下很好地重定向错误?

转载 作者:行者123 更新时间:2023-12-03 07:55:58 25 4
gpt4 key购买 nike

如果我有处理 friend 管理的 View ,则意味着有一个 View 可以处理添加,删除,阻止,取消阻止以及接受/拒绝成为 friend 的邀请。我遇到的问题是,当我尝试向最终以不应该使用的URL结尾的用户提供有意义的错误时。

例如,如果 User1 User2 已经是 friend ,并且 User1 转到将 User2 作为 friend 添加的URL,而不是像他们不是 friend 一样显示表单,并且unique_together = (('user_from', 'user_to'),)上显示的表单失败警告消息,并在显示表单之前将它们重定向到适当的页面。

像这样

def add_friend(request, username):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
messages.error(request, 'A user with the username %s does not exist. \
Try searching for the user below.' % username)
return HttpResponseRedirect(reverse('friends_find_friend'))

if Friend.objects.are_friends(request.user, user):
messages.error(request, 'You are already friends with %s' % user)
return HttpResponseRedirect(reverse('profiles_profile_detail', args=[user]))

如果没有这样的用户,它还包括检查和有意义的错误消息(而不是404)。

这很容易处理,但是随着其他检查的发展,
def add_friend(request, username):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
messages.error(request, 'A user with the username %s does not exist. \
Try searching for the user below.' % username)
return HttpResponseRedirect(reverse('friends_find_friend'))

if user == request.user:
messages.error(request, 'You are already friends with yourself')
return HttpResponseRedirect(reverse('friends_find_friend'))

if Enemy.objects.is_blocked(request.user, user):
messages.error(request, '%s has blocked you from adding them as a friend' % user)
return HttpResponseRedirect(reverse('friends_find_friend'))

if Enemy.objects.has_blocked(request.user, user):
messages.error(request, 'You have blocked %s so you cannot add them as a friend' % user)
return HttpResponseRedirect(reverse('profiles_profile_detail', args=[user]))

if Friend.objects.are_friends(request.user, user):
messages.error(request, 'You are already friends with %s' % user)
return HttpResponseRedirect(reverse('profiles_profile_detail', args=[user]))

if FriendRequest.objects.invitation_sent(request.user, user):
messages.error(request, 'You already sent %s a request. You need to \
wait for them to reply to it.' % user)
return HttpResponseRedirect(reverse('friends_pending'))

if FriendRequest.objects.invitation_received(request.user, user):
messages.error(request, '%s already sent you a request and is waiting \
for you to respond to them.' % user)
return HttpResponseRedirect(reverse('friends_pending'))

所有这些都在重复
  • remove_friend
  • block_user
  • unblock_user
  • 未决邀请

  • 如果在 shell 中绕过 View 并且独立使用表单,则还会进一步复制为表单验证错误。

    我要问的是,是否有一种更Python的方式来完成此任务,而又不会过度复制和粘贴?

    编辑:

    我一直在试图解决这个问题,并且想知道这样的事情是否是个好方法。
    tests = ((Enemy.objects.is_blocked, 'This user has blocked you', reverse('friends_find_friend')),
    (Enemy.objects.has_blocked, 'You have blocked this user', reverse('profiles_profile_detail', args=[user])),)

    for test in tests:
    if test[0](request.user, user):
    messages.error(request, test[1])
    return HttpResponseRedirect(test[2])

    测试将在类似于url模式的另一个文件中定义,并且装饰器将包装view函数以运行所有测试,如果一切失败,则重定向,如果一切正常,最后将其传递给view函数。这将是一种有效的方法,而不会阻塞数百行样板代码的 View 文件吗?

    Edit2 :

    我也很想看看别人如何做类似的事情。我怀疑我是第一个想要向用户显示消息而不是仅仅抛出404页面的人。

    最佳答案

    Python装饰器是完美的选择。

    定义您在装饰器中执行的所有验证,并以此装饰所有add_friendremove_friend等。

    更新:

    对于您的情况,它将看起来像这样:

    def do_friending_validation(fun):
    def validate_function(*args,**kwargs):
    try:
    user = User.objects.get(username=username)
    except User.DoesNotExist:
    messages.error(request, 'A user with the username %s does not exist. \
    Try searching for the user below.' % username)
    return HttpResponseRedirect(reverse('friends_find_friend'))

    if user == request.user:
    messages.error(request, 'You are already friends with yourself')
    return HttpResponseRedirect(reverse('friends_find_friend'))

    if Enemy.objects.is_blocked(request.user, user):
    messages.error(request, '%s has blocked you from adding them as a friend' % user)
    return HttpResponseRedirect(reverse('friends_find_friend'))

    if Enemy.objects.has_blocked(request.user, user):
    messages.error(request, 'You have blocked %s so you cannot add them as a friend' % user)
    return HttpResponseRedirect(reverse('profiles_profile_detail', args=[user]))

    if Friend.objects.are_friends(request.user, user):
    messages.error(request, 'You are already friends with %s' % user)
    return HttpResponseRedirect(reverse('profiles_profile_detail', args=[user]))

    if FriendRequest.objects.invitation_sent(request.user, user):
    messages.error(request, 'You already sent %s a request. You need to \
    wait for them to reply to it.' % user)
    return HttpResponseRedirect(reverse('friends_pending'))

    if FriendRequest.objects.invitation_received(request.user, user):
    messages.error(request, '%s already sent you a request and is waiting \
    for you to respond to them.' % user)
    return HttpResponseRedirect(reverse('friends_pending'))
    fun(*args,**kwargs)

    return validate_function

    @do_friending_validation
    def add_friend(request, username):

    #Do your stuff here

    @do_friending_validation
    def remove_friend(request, username):

    #Do your stuff here

    关于django - 在没有太多复制/粘贴的情况下很好地重定向错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1900365/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com