将数据从 django 表单传递到 ListView

Posted

技术标签:

【中文标题】将数据从 django 表单传递到 ListView【英文标题】:Passing data from django form to ListView 【发布时间】:2018-05-28 23:00:27 【问题描述】:

上面是我正在尝试构建的图像:一个位于顶部的表单,而显示结果列表的区域位于下方。当我点击“开始!”时,下面的部分并没有像我希望的那样呈现列表。另外,我不确定这是否是这样做的“正确”方式。

我使用的基于类的视图:

class EntryListView(ListView):
    template_name = 'finance/entry_list.html'
    now = datetime.now()
    year = now.year
    context_object_name = 'entry_list'
    model = Entry
    paginate_by = 10
    month_list = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
                  'November', 'December']
    year_list = list(range(Entry.objects.earliest('input_date').input_date.year,
                           Entry.objects.latest('input_date').input_date.year))

    def get_context_data(self, **kwargs):
        context = super(EntryListView, self).get_context_data(**kwargs)

        # https://***.com/questions/18232851/django-passing-variables-to-templates-from-class-based-views
        context.update(
            'month_list': self.month_list,
            'year_list': self.year_list,
        )
        return context

    # This method ensures that I can customize the list of entries returned.
    def get_queryset(self):

        # https://***.com/questions/22902457/django-listview-customising-queryset
        if self.request.method == 'GET':
            print('I have entered here!')
            month = self.request.GET.get('month')
            year = self.request.GET.get('year')
            print('month: ' + str(month))
            print('year: ' + str(year))
            if month or year is None:
                return Entry.objects.filter(input_date__month=datetime.now().month,
                                            input_date__year=datetime.now().year).order_by('-input_date').all()
            else:
                return Entry.objects.filter(input_date__month=month,
                                            input_date__year=year).order_by('-input_date').all()

这是我的 urls.py:

url(r'entry/$', login_required(views.EntryListView.as_view()), name='list_entries'),

EntryListView 还负责确保使用正确的“下拉值”填充表单。

这是模板:

% extends 'base.html' %
% block body_content %
    <div class="wrapper">
        % include 'finance/finance_sidebar.html' % <!-- Add this for inheritance -->
        <div class="container">
            <div class="row">
                <form class="well contact-form" method='GET'>
                    <label>Month:</label>
                    <select class="well form-control" name="month">
                        % for month in month_list %
                            <option value=" forloop.counter "> month </option>
                        % endfor %
                    </select>
                    <label>Year:</label>
                    <select class="well form-control" name="year">
                        % for year in year_list %
                            <option value=" year "> year </option>
                        % endfor %
                    </select>
                    <button type="submit" class="btn btn-default">Go!</button>
                </form>
            </div>
            <div class="row">
                % if entry_list %
                <div class="container">
                    <table class="table table-hover">
                        <thead>
                            <tr>
                                <th>No.</th>
                                <th >Input Date</th>
                                <th>Category</th>
                                <th>Tag</th>
                                <th>Description</th>
                                <th>Value</th>
                                <th>Transfer Type</th>
                                <th>Remarks</th>
                                <th>Edit</th>
                                <th>Delete</th>
                            </tr>
                        </thead>
                        <tbody>
                        % for entry in entry_list %
                            <tr>
                                <td> forloop.counter </td>
                                <td> entry.input_date|date:'d M Y' </td>
                                <td> entry.category </td>
                                <td> entry.tag </td>
                                <td> entry.description </td>
                                <td>$ entry.value </td>
                                <td> entry.transfer_type </td>
                                <td> entry.remarks </td>
                                <td>
                                    <form class="flex-container" method="post" action="% url 'finance:update_entry' pk=entry.id %" >
                                        % csrf_token %
                                        <div class="input-group">
                                            <input type="hidden" name="id" value=" entry.id ">
                                            <button name="update" type="submit" class="btn btn-warning">EDIT </button>
                                        </div>
                                    </form>
                                </td>
                                <td>
                                    <form class="flex-container" method="post" action="% url 'finance:delete_entry' %" >
                                        % csrf_token %
                                        <div class="input-group">
                                            <input type="hidden" name="id" value=" entry.id ">
                                            <button name="delete" type="submit" class="btn btn-danger">DELETE </button>
                                        </div>
                                    </form>
                                </td>
                            </tr>
                        % endfor %
                        </tbody>
                    </table>
                </div>
                <div class="col-sm-7 col-sm-offset-5">
                    % if is_paginated %
                        <div class="pagination">
                            <span class="page-links">
                                % if page_obj.has_previous %
                                    <a href="/?page= page_obj.previous_page_number ">previous</a>
                                % endif %
                                <span class="page-current">
                                    Page  page_obj.number  of  page_obj.paginator.num_page .
                                </span>
                                % if page_obj.has_next %
                                    <a href="/?page= page_obj.next_page_number ">next</a>
                                % endif %
                            </span>
                        </div>
                    % endif %
                </div>
            % else %
                <p>Please make sure you have specified a month and the year.</p>
            % endif %
            </div>
        </div>
    </div>
% endblock %

我又来了,不确定这是否是处理它的正确方法。我见过一种叫做 Mixins 的东西,但我不知道如何使用它们。我在调试时做了一些打印语句,我发现表单中的数据确实可以在get_queryset() 方法中访问。我还确保我的数据库有这样的记录,我什至在我的 python shell 中输入它以确保查询没有错误。

【问题讨论】:

【参考方案1】:

您认为您的if-else 声明是错误的。 if month or year is None: 将始终评估为 true,因为它可以重写为 if (month) or (year is None) 并且您实际上是在将月份值发布到您的视图中。

相反,您可以将其重写为:if month is None or year is None:

【讨论】:

以上是关于将数据从 django 表单传递到 ListView的主要内容,如果未能解决你的问题,请参考以下文章

将模板变量从 URL 传递到 Django 中的 FormPreview

将变量从视图传递到表单 Django

Django 将输入数据从 HTML 文件传递​​到 python 脚本,然后将最终数据发送到另一个 HTML 文件

将数据从按钮传输到下一页的帖子表单。 Django的

如何传递从 django 表单操作 url 的下拉列表中选择的项目的 ID?

从 Django HTML 表单中检索数据并将其传递给 MySQL 数据库