【问题标题】:Django redirect to previous page not workingDjango重定向到上一页不起作用
【发布时间】:2016-11-02 23:23:29
【问题描述】:

嗨,我想在 django 中提交表单后重定向到上一个。它已成功重定向到上一页,但未发生发布操作。如果我删除 action 属性,我可以成功发布数据。

这是我的表单模板。

{% extends 'musicapp/base.html' %} {% block content %}
<!-- <h1>New post</h1> -->
<form method="POST" action={{ request.META.HTTP_REFERER }} class="post-form">{% csrf_token %}



<div class="add_track_form" >

  <div class="col-sm-6">
      <section class="panel panel-default">
          <header class="panel-heading font-bold">Add Genre</header>
          <div class="panel-body">
              <form action="{% url 'post_list' %}" role="form">
                  <div class="form-group">

                      <label>Title</label>
                       {{ form.name }}
                  </div>
                  <input type="hidden" name="next" value="{{ request.path }}">
                  <button type="submit" class="btn btn-sm btn-default">Submit</button>
              </form>
          </div>
      </section>
  </div>

</div>


</form>

{% endblock %}

这是views.py文件

from django.shortcuts import render, get_object_or_404, redirect, render_to_response
from django.http import HttpResponseRedirect
from .forms import AddTrackForm, AddGenreForm
from django.http import HttpResponse
from .models import Track, Genre
from . import getAlbumArt

# Create your views here.
def home(request):
    tracks = Track.objects.all().order_by('created_date')
    return render(request, 'musicapp/post_list.html', {'tracks': tracks})

def post_detail(request, pk):
    track = get_object_or_404(Track, pk=pk)
    # print post
    return render(request, 'musicapp/post_detail.html', {'track': track})
# def post_new(request):
#     form = AddTrackForm()
#     return render(request, 'musicapp/post_edit.html', {'form': form})

def post_new(request):
    if request.method == "POST":
        form = AddTrackForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            artist = request.POST.get("artist", "")
            album = request.POST.get("album", "")
            # print artist, album
            urlArt = getAlbumArt.getAlbumArtURL(album, artist)
            print urlArt
            if urlArt:
                post.cover_image_url = urlArt
            if post.album == '*':
                post.album = 'Unknown'
            post.save()
            tracks = Track.objects.all().order_by('created_date')
            return render(request, 'musicapp/post_list.html', {'tracks': tracks})
    else:
        form = AddTrackForm()
    return render(request, 'musicapp/post_edit.html', {'form': form})

def post_edit(request, pk):
    post = get_object_or_404(Track, pk=pk)
    if request.method == "POST":
        form = AddTrackForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            artist = request.POST.get("artist", "")
            album = request.POST.get("album", "")
            # print artist, album
            urlArt = getAlbumArt.getAlbumArtURL(album, artist)
            print urlArt
            if urlArt:
                post.cover_image_url = urlArt
            if post.album == '*':
                post.album = 'Unknown'
            post.save()
            tracks = Track.objects.all().order_by('created_date')
            return redirect('post_detail', pk=post.pk)
    else:
        form = AddTrackForm(instance=post)
    return render(request, 'musicapp/post_edit.html', {'form': form})

def genre(request):
    tracks = Track.objects.all().order_by('created_date')
    genres = Genre.objects.all()
    return render(request, 'musicapp/genre.html', {'genres': genres, 'tracks': tracks})

def genre_songs(request, pk):
    genres = Genre.objects.all()
    genre_obj = get_object_or_404(Genre, pk=pk)
    tracks = genre_obj.track_set.all()
    # print post
    return render(request, 'musicapp/genre_songs.html', {'genres': genres, 'genre' : genre_obj, 'tracks': tracks})

def genre_new(request):
    if request.method == "POST":
        form = AddGenreForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            genres = Genre.objects.all()
            print request.META.HTTP_REFERER
            next = request.POST.get('next', '/')
            # return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
            # print next
            # return HttpResponseRedirect(next)
            # return HttpResponseRedirect('/')
            return render_to_response('musicapp/post_edit.html', {'form': AddTrackForm()})
    else:
        form = AddGenreForm()
    return render(request, 'musicapp/genre_edit.html', {'form': form})

这些是 URL 路由。

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.home, name='post_list'),
    url(r'^track/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
    url(r'^track/new/$', views.post_new, name='post_new'),
    url(r'^track/(?P<pk>\d+)/edit/$', views.post_edit, name='post_edit'),
    url(r'^genre/$', views.genre, name='genre_list'),
    url(r'^genre/(?P<pk>\d+)/$', views.genre_songs, name='genre_songs'),
    url(r'^genre/new/$', views.genre_new, name='genre_new'),
]

【问题讨论】:

    标签: html django url-redirection


    【解决方案1】:

    这可能看起来很长一段时间,但应用了 Ian Prince 的推理。请注意已经进行的一些更改。

    {% extends 'musicapp/base.html' %} {% block content %}
    <!-- <h1>New post</h1> -->
    <form method="POST" class="post-form">{% csrf_token %}
    
    
    
    <div class="add_track_form" >
    
      <div class="col-sm-6">
          <section class="panel panel-default">
              <header class="panel-heading font-bold">Add Genre</header>
              <div class="panel-body">
                  <form action="{% url 'post_list' %}" role="form">
                      <div class="form-group">
    
                          <label>Title</label>
                           {{ form.name }}
                      </div>
                      <input type="hidden" name="next" value="{{ request.META.HTTP_REFERER }}">
                      <button type="submit" class="btn btn-sm btn-default">Submit</button>
                  </form>
              </div>
          </section>
      </div>
    
    </div>
    
    
    </form>
    
    {% endblock %}

    这些变化包括:

    action='{{ request.META.HTTP_REFERER }}'
    <!-- although this was posted as: action={{ request.META.HTTP_REFERER }} -->

    以及变化:

    value="{{ request.path }}"

    到:

    value="{{ request.META.HTTP_REFERER }}"

    这解决了我的问题。希望能解决你的问题

    【讨论】:

      【解决方案2】:

      我认为我有一个更简单的方法。

      模板:

      <div hidden>
           <input name="url_get" value={{ url_ref }}>
      </div>
      

      查看:

      url_get = request.POST.get('url_get')
      if url_get:
         url_ref = url_get
      else:
         url_ref = request.META.get('HTTP_REFERER')
      args['url_ref'] = url_ref
      

      所以,我们总是有第一个 url

      【讨论】:

        【解决方案3】:

        所以我通过比较我们单击链接的 URL 然后根据上一个设置隐藏字段来解决我的问题 URL (request.META.HTTP_REFERER) 并根据我从模板中获取的标志值进行重定向。

        这是我的模板

        {% extends 'musicapp/base.html' %} {% block content %}
        <!-- <h1>New post</h1> -->
        <form method="POST" class="post-form">{% csrf_token %}
        
        
        
        <div class="add_track_form" >
        
          <div class="col-sm-6">
              <section class="panel panel-default">
                  <header class="panel-heading font-bold">Add Genre</header>
                  <div class="panel-body">
        
                          <div class="form-group">
        
                              <label>Title</label>
                               {{ form.name }}
                          </div>
        
                          {% if 'track/new/' in request.META.HTTP_REFERER %}
                            <input class="form-control" type="hidden" value = 0 id="flag" maxlength="50" name="flag" type="text">
                          {% else %}
                            <input class="form-control" type="hidden" value = 1 id="flag" maxlength="50" name="flag" type="text">
                          {% endif %}
                          <button type="submit" class="btn btn-sm btn-default">Submit</button>
        
                  </div>
              </section>
          </div>
        
        </div>
        
        
        </form>
        
        {% endblock %}
        

        这是视图函数:

        def genre_new(request):
            if request.method == "POST":
                form = AddGenreForm(request.POST)
                if form.is_valid():
                    post = form.save(commit=False)
                    redirect_flag = request.POST.get("flag", "")  # redirect to different places depending upon where it was clicked
                    post.save()
                    genres = Genre.objects.all()
                    print redirect_flag
                    if redirect_flag == '0':
                        return HttpResponseRedirect(reverse('post_new'))
                    elif redirect_flag == '1':
                        return HttpResponseRedirect(reverse('genre_list'))
                    else:
                        return HttpResponseRedirect('/')
        
            else:
                form = AddGenreForm()
            return render(request, 'musicapp/genre_edit.html', {'form': form})
        

        有更简单的方法吗?

        【讨论】:

          【解决方案4】:

          看看这个:

          <input type="hidden" name="next" value="{{ request.path }}" />
          

          request.path 提供当前页面的路径,而不是上一个页面。因此,您当前正在提交表单提交所在页面的下一个值。

          {{ request.META.HTTP_REFERER }} 提供参考页面。那么,为什么要将表单发布到上一页呢?不过应该注意的是,它的值可能是None(或者引用页面可能来自另一个域)。

          我假设您已经切换了表单的操作参数和“下一个”隐藏输入的值。否则,您可能有不必要的复杂逻辑。

          【讨论】:

          • 我想我误解了 action 属性的含义。我虽然它只是在发布数据后重定向到给定的 URL。现在我明白为什么这行不通了。但是使用 request.path 我能够成功重定向到上一页
          • 很高兴听到@Angersmash。如果此答案或任何其他答案解决了您的问题,请标记为已回答并按您的意愿投票。
          • 我在两个不同的地方链接一个页面,我想在将表单发布到两个不同的 URL 后重定向,具体取决于单击该表单 URL 的位置。我正在考虑为它维护会话变量。有更简单的方法吗?
          • 如果需要,您的视图还可以将数据提交到另一个 url,或者根据单击的按钮执行业务逻辑。如果您在 html 中使用带有 value 属性的命名输入元素(其值将显示在您的 request.POST 中),您可以知道单击了哪个按钮。见here。如果没有自定义 Javascript,您的表单不会从客户端计算机一次提交到两个 url。这不是 html 表单的常见行为。
          【解决方案5】:

          在你的 urls.py 中替换

           url(r'^$', views.home, name='post_list'),
          

           url(r'^postlist/$',views.home, name='post_list'),
          

          在你的表单中

          <form action="{% url 'post_list' %}" role="form">
          

          成为

          <form action="/postlist" role="form" method="POST">
          

          【讨论】:

            【解决方案6】:

            您有两种形式,它们是嵌套的。内部表单使用 GET(如果没有指定,则默认使用 GET),外部表单使用 POST。这纯粹是混乱,你不应该这样做。如果你解决了这个问题,我相信这个错误也会得到修复。

            {{ request.META.HTTP_REFERER }} 不一定是您想到的上一页。您不应该以这种方式使用它。我会使用 GET(例如使用 '?prev=/url/before/form/')来记住用户来自哪个页面。

            【讨论】:

            • 我没有注意到 HTML 中有两个表单标签。从我的其他表单的 html 复制粘贴它时,我可能错过了它。感谢您的纠正。
            猜你喜欢
            • 2020-06-12
            • 1970-01-01
            • 1970-01-01
            • 2014-08-20
            • 2021-07-23
            • 2020-12-08
            • 2014-11-22
            • 2018-05-14
            • 2017-07-05
            相关资源
            最近更新 更多