【问题标题】:Django - ListView with form, How to redirect back to the Form page?Django - 带有表单的 ListView,如何重定向回表单页面?
【发布时间】:2020-09-10 11:24:12
【问题描述】:

所以,我有一个带有练习列表的 ListView(每页分页 1 个)。在每个页面中,我几乎没有用户需要填写的输入。我设法找到了如何将 ListView 与表单附加的解决方案,但我找不到关于如何在提交后保持在同一页面上的解决方案。

网址:

urlpatterns = [
    path('programs/', ProgramListView.as_view(), name='web-programs'),
    path('programs/<int:pk>/', ExerciseListView.as_view(), name='program-detail'),
    path('data/', views.add_data, name='data-submit'),

views.py(使用 def form_valid 更新):

class ExerciseListView(LoginRequiredMixin,FormMixin, ListView):
    model = Exercise
    context_object_name = 'exercises'
    form_class = DataForm
    paginate_by = 1

    def get_queryset(self):
        program_num = get_object_or_404(Program, pk=self.kwargs.get('pk'))
        return Exercise.objects.filter(program=program_num)

    def form_valid(self, dataform):
        program_num = get_object_or_404(Program, pk=self.kwargs.get('pk'))
        exercises = Exercise.objects.filter(program=program_num)
        for exe in exercises:
            dataform.instance.exercise = exe.pk
            return super(ExerciseListView, self).form_valid(dataform)


def add_data(request):
    if request.method == "POST":
        form = DataForm(request.POST)

        if form.is_valid():
            form.save()
            # Data.objects.create(address=form.cleaned_data['form'])
            return redirect(?)

模板.html:

{% extends "program/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <h3> Program Exercises List </h3>
    {% for exercise in exercises %}
        <article class="media content-section">
            <div class="media-body">
                <div class="article-metadata">
                    {% if user.is_superuser %}
                        <a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'exercise-update' exercise.id %}">Update</a>
                        <a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'exercise-delete' exercise.id %}">Delete</a>
                        <p class="article-content">{{ exercise.name }}</p>
                    {% else %}
                        <p class="article-content">{{ exercise.name }}</p>
                    {% endif %}
                </div>
                <div class="article-metadata">
                    <p class="article-content">{{ exercise.description }}</p>
                    <p class="article-content">{{ exercise.breath_method}}</p>
                    <p class="article-content">{{ exercise.recovery_method }}</p>
                    <p class="article-content">{{ exercise.measure_method }}</p>
                    <p class="article-content">{{ exercise.load_share }}</p>
                    <p class="article-content">{{ exercise.notes }}</p>
                    <p class="article-content">{{ exercise.extra_info }}</p>
                    <p class="article-content">{{ exercise.reps }}</p>
                    <p class="article-content">{{ exercise.sets }}</p>
                </div>
                  <form action="{% url 'data-submit' %}" method="POST" enctype="multipart/form-data">
                        {% csrf_token %}
                        <fieldset class="form-group">
                            <legend class="border-bottom mb-4">Exercise Measurements</legend>
                            {{ form|crispy }}
                        </fieldset>
                        <div class="form-group">
                            <button class="btn btn-outline-info" type="submit">Save</button>
                        </div>
                  </form>
            </div>
        </article>
    {% endfor %}
    {% if is_paginated %}

        {% if page_obj.has_previous %}
            <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous Exercise</a>
        {% endif %}

        {% if page_obj.has_next %}
            <a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next Exercise</a>
        {% else %}
            <a class="btn btn-outline-info mb-4" href="{% url 'web-home' %}">Exit</a>
        {% endif %}

    {% endif %}
{% endblock content %}

forms.py:

class DataForm(forms.ModelForm):
    class Meta:
        model = Data
        fields = ['exercise', 'set_number', 'spo2', 'hr']

在 views.py 中,我将“重定向”保留为“?”因为我不知道要在那里添加什么。 我无法更改 template.html 中的“操作”,因为此链接适用于 def add_data(request) 所以它会保存我的输入。 一旦我提交,它会将新数据保存到我的数据库中,但我不知道如何留在同一页面上继续我的练习。

谢谢。

【问题讨论】:

    标签: python django forms listview


    【解决方案1】:

    您有“练习中的程序”,因此使用它获取程序 ID

    from django.shortcuts import redirect, reverse
    def add_data(request):
        page=request.GET.get('page')
        page='?page={}'.format(page) if page else ''
        if request.method == "POST":
            form = DataForm(request.POST)
            if form.is_valid():
                data=form.save()
                return redirect(reverse('program-detail', kwargs={'pk':data.exercise.program.pk})+ page)
    

    为了重定向到同一页面,您检查并在 url 中以表单操作传递页面参数,例如

    <form action="{% url 'data-submit' %}{%if request.GET.page%}?page={{request.GET.page}}{%endif%}" method="POST" enctype="multipart/form-data">{% csrf_token %}
    

    【讨论】:

    • 是的,你是对的,我确实有它作为外键。我现在试了一下,他好像不认识——“'program-detail', pk=data.exercise.program.pk”。我在数据下方有一条红线。知道为什么吗?
    • 我认为redirect方法不能接收pk作为参数。我在文档中找不到它,但我可能错了。
    • 你也可以使用用户完整的url重定向('/programs/{}/'.format(data.exercise.program.id))
    • 我尝试了两种方式,它无法识别“pk=data....”。知道为什么吗?谢谢。
    【解决方案2】:
    1. 你需要使用jQuery来实现这个结果。下载,粘贴到js文件夹,添加到program/base.html
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    
    1. 建议你在base.html中添加一个js块 文件底部的某处
    {% block js %}{% endblock js %} 
    
    1. 然后,这样做:
    <block js>
    <script>
    $("#submit-btn").submit(function(event) {
      // prevent default action, so no page refreshing
      event.preventDefault();
      var form = $(this);
      var posting = $.post( form.attr('action'), form.serialize() );
    
      posting.done(function(data) {
        // done
      });
      posting.fail(function(data) {
        // fail
      });
    });
    </script>
    <endblock>
    
    ...
    
    <form action="{% url 'data-submit' %}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <fieldset class="form-group">
    <legend class="border-bottom mb-4">Exercise Measurements</legend>
      {{ form|crispy }}
    </fieldset>
    <div class="form-group">
      <button class="btn btn-outline-info" id="submit-btn" type="submit">Save</button>
    </div>
    </form>
    

    【讨论】:

    • 有点迷失了这个解决方案。这将如何帮助我重定向回来?对不起,我的误解,我在这个框架上使用的时间不长。
    • 它在不打开新视图/网址的情况下发送发布请求,因此您停留在同一页面上。它被称为 ajax。
    • 好的,作为一个很好的解决方案是有意义的。我在函数的“重定向”中添加了什么?
    • 什么都没有。请改用return HttpResponse(status=200)。或任何其他代码,如果表单无效等..
    • 我需要创建program/base.html吗?究竟在哪里找到它?在我的模板中?我需要打电话吗?谢谢。
    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 2018-10-20
    • 2012-07-25
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2013-08-17
    相关资源
    最近更新 更多