2016-10-22 28 views
2

在一個Django網站中,我有一個分頁ListView,它顯示了某個對象的列表,每頁100個。在Django中接受輸入ListView

我想在此頁面上包含一個文本框並接受+處理用戶輸入。但在Django,這需要我要麼:

我)使用FormView(在這種情況下,我失去了分頁),或

II)收件,我手動處理分頁和表格處理基於函數的觀點。

是否有第三種方法來實現我想要做的,理想情況下不會中斷ListView

+0

爲什麼不使用一個簡單的基於函數的視圖,您可以輕鬆處理列表和表單? – ettanany

+0

@ettanany:是的,通過(ii)中的非cbvs,我的意思是基於函數的視圖 –

+0

我明白了。我認爲你的情況是類似於這個[ListView和CreateView在一個模板Django](http://stackoverflow.com/questions/19341568/listview-and-createview-in-one-template-django) – ettanany

回答

2

在我看來,每個視圖都應該有一個目的。這並不意味着你不能在一個頁面中擁有多個表單元素。您可以通過

製作一個只能處理數據的普通視圖。您可以設置視圖的網址,然後對該視圖進行ajax調用。這可能是,如果你願意使用JavaScript爲以及容易實現的(簡單XHR方法,模糊,改變事件)

例如: - 。

class FormElementProcess(View): 
    def post(self,request,*args,**kwargs): 
     #Do your processing and return httpresponse 

您可以進一步自定義上面的類,也如果還使用表單類,則使用表單處理和返回表單數據。

這將是我猜的方式。假設我的主頁有幾十個表單。形式像 - >搜索,登錄,註冊等。我不會通過我的IndexView處理所有事情。當應用程序規模變大時,這會使所有事情複雜化。

2)如果頁面刷新,那麼我建議你使用FormMixin。 有一個很好的執行,我發現製作FormListView

from django.http import Http404 
from django.utils.translation import ugettext as _ 
from django.views.generic.edit import FormMixin 
from django.views.generic.list import ListView 

class FormListView(FormMixin, ListView): 
    def get(self, request, *args, **kwargs): 
     # From ProcessFormMixin 
     form_class = self.get_form_class() 
     self.form = self.get_form(form_class) 

     # From BaseListView 
     self.object_list = self.get_queryset() 
     allow_empty = self.get_allow_empty() 
     if not allow_empty and len(self.object_list) == 0: 
      raise Http404(_(u"Empty list and '%(class_name)s.allow_empty' is False.") 
          % {'class_name': self.__class__.__name__}) 

     context = self.get_context_data(object_list=self.object_list, form=self.form) 
     return self.render_to_response(context) 

    def post(self, request, *args, **kwargs): 
     return self.get(request, *args, **kwargs) 


class MyListView(FormListView): 
    form_class = MySearchForm 
    model = MyModel 
    # ... 

Detailed Code Explanation

您將修改後的方法還做你的處理。你可以直接使用表單類,包含來自請求處理的參數。

1

使用基於函數的視圖來實現你想要的是如下的例子:

聯繫人/ models.py:

from django.db import models 
from django.utils.encoding import python_2_unicode_compatible 


@python_2_unicode_compatible 
class Contact(models.Model): 
    email = models.EmailField(unique=True) 
    first_name = models.CharField(max_length=40, blank=True) 
    last_name = models.CharField(max_length=40, blank=True) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

    def __str__(self): 
     return self.email 

聯繫人/ forms.py:

from django import forms 


class UserForm(forms.Form): 
    search = forms.CharField(label='Search', max_length=100) 

contacts/views.py:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 
from django.shortcuts import render, redirect 
from .models import Contact 
from .forms import UserForm 


def my_contacts(request): 
    form = UserForm() 
    if request.method == 'POST': 
     form = UserForm(request.POST) 
     if form.is_valid(): 
      # Do something with form data here 
      print(form.cleaned_data['search']) 
     redirect('my_contacts') 

    contacts_list = Contact.objects.all() 
    page = request.GET.get('page', 1) 

    paginator = Paginator(contacts_list, 10) 
    try: 
     contacts = paginator.page(page) 
    except PageNotAnInteger: 
     contacts = paginator.page(1) 
    except EmptyPage: 
     contacts = paginator.page(paginator.num_pages) 

    return render(request, 'contacts/contacts.html', {'contacts': contacts, 'form': form}) 

聯繫人/ urls.py:

from django.conf.urls import patterns, url 

urlpatterns = patterns(
    'contacts.views', 
    url(r'^$', 'my_contacts', name='my_contacts'), 
) 

模板/聯繫人/ contacts.html:

{% extends 'base.html' %} 

{% block 'container' %} 
<div class="row"> 
    <div class="col-sm-12"> 
    <form action="" method="post"> 
     {% csrf_token %} 
     {{ form }} 
     <input type="submit" value="Submit" /> 
    </form> 
    </div> 
</div> 
<div class="row"> 
<div class="col-sm-12"> 
<table class="table table-bordered"> 
    <thead> 
    <tr> 
     <th>Email</th> 
     <th>First name</th> 
     <th>Last name</th> 
    </tr> 
    </thead> 
    <tbody> 
    {% for contact in contacts %} 
     <tr> 
     <td>{{ contact.email }}</td> 
     <td>{{ contact.first_name }}</td> 
     <td>{{ contact.last_name }}</td> 
     </tr> 
    {% endfor %} 
    </tbody> 
</table> 

{% if contacts.has_other_pages %} 
    <ul class="pagination"> 
    {% if contacts.has_previous %} 
     <li><a href="?page={{ contacts.previous_page_number }}">&laquo;</a></li> 
    {% else %} 
     <li class="disabled"><span>&laquo;</span></li> 
    {% endif %} 
    {% for i in contacts.paginator.page_range %} 
     {% if contacts.number == i %} 
     <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li> 
     {% else %} 
     <li><a href="?page={{ i }}">{{ i }}</a></li> 
     {% endif %} 
    {% endfor %} 
    {% if contacts.has_next %} 
     <li><a href="?page={{ contacts.next_page_number }}">&raquo;</a></li> 
    {% else %} 
     <li class="disabled"><span>&raquo;</span></li> 
    {% endif %} 
    </ul> 
{% endif %} 
</div> 
</div> 
{% endblock %} 

模板/ base.html文件:

{% load static %} 

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <meta name="description" content=""> 
    <meta name="author" content=""> 
    <title>{% block 'title'%}{% endblock %}</title> 
    <!-- Bootstrap Core CSS --> 
    <link href={% static 'css/bootstrap.min.css' %} rel="stylesheet"> 
</head> 
<body> 
    <!-- Page Content --> 
    <div class="container" style="padding-top: 50px;"> 
     {% block 'container' %}{% endblock %} 
    </div> 
    <!-- /.container --> 

    <script src="{% static 'js/jquery.js' %}"></script> 
    <!-- Bootstrap Core JavaScript --> 
    <script src="{% static 'js/bootstrap.min.js' %}"></script> 
</body> 
</html>