2011-06-20 24 views
20

Chế độ xem chính là một ListView được phân trang đơn giản và tôi muốn thêm biểu mẫu tìm kiếm vào đó.Chế độ xem dựa trên lớp Django ListView với biểu mẫu

Tôi nghĩ một cái gì đó như thế này sẽ làm các trick:

class MyListView(ListView, FormView): 
    form_class = MySearchForm 
    success_url = 'my-sucess-url' 
    model = MyModel 
    # ... 

Nhưng dường như tôi đã nhận nó sai .. và tôi không thể tìm thấy làm thế nào để làm điều đó trong các tài liệu chính thức.

Đề xuất?

Trả lời

5

Tôi cũng đang tìm kiếm một giải pháp phù hợp. Nhưng không thể tìm thấy bất kỳ như vậy đã phải đi lên với của riêng tôi. views.py

class VocationsListView(ListView): 

    context_object_name = "vocations" 
    template_name = "vocations/vocations.html" 
    paginate_by = 10 

    def get_queryset(self): 
     get = self.request.GET.copy() 
     if(len(get)): 
      get.pop('page') 
     self.baseurl = urlencode(get) 
     model = Vocation 
     self.form = SearchForm(self.request.GET) 
     filters = model.get_queryset(self.request.GET) 
     if len(filters): 
      model = model.objects.filter(filters) 
     else: 
      model = model.objects.all() 
     return model 



def get_context_data(self, **kwargs): 
    context = super(VocationsListView, self).get_context_data(**kwargs) 
    context['form'] = self.form 
    context['baseurl']= self.baseurl 
    return context 

models.py

class Vocation(models.Model): 
    title = models.CharField(max_length = 255) 
    intro = models.TextField() 
    description = models.TextField(blank = True) 
    date_created = models.DateTimeField(auto_now_add = True) 
    date_modified = models.DateTimeField(auto_now = True) 
    created_by = models.ForeignKey(User, related_name = "vocation_created") 
    modified_by = models.ForeignKey(User, related_name = "vocation_modified") 

    class Meta: 
     db_table = "vocation" 

    @property 
    def slug(self): 
     return defaultfilters.slugify(self.title) 

    def __unicode__(self): 
     return self.title 

    @staticmethod 
    def get_queryset(params): 

     date_created = params.get('date_created') 
     keyword = params.get('keyword') 
     qset = Q(pk__gt = 0) 
     if keyword: 
      qset &= Q(title__icontains = keyword) 
     if date_created: 
      qset &= Q(date_created__gte = date_created) 
     return qset 

nên về cơ bản tôi thêm đoạn mã này để mỗi lớp mô hình, nơi mà tôi muốn thực hiện các chức năng tìm kiếm. Điều này là do bộ lọc cho mỗi mô hình phải được chuẩn bị một cách rõ ràng

@staticmethod 
def get_queryset(params): 

    date_created = params.get('date_created') 
    keyword = params.get('keyword') 
    qset = Q(pk__gt = 0) 
    if keyword: 
     qset &= Q(title__icontains = keyword) 
    if date_created 
     qset &= Q(date_created__gte = date_created) 
    return qset 

nó chuẩn bị bộ lọc qset mà tôi sử dụng để lấy dữ liệu từ mô hình

26

Những câu trả lời đã giúp rất nhiều để chỉ đạo tôi trong đúng hướng. Cảm ơn.

Để triển khai, tôi cần một chế độ xem biểu mẫu trả về một ListView trên cả nhận và đăng. Tôi không muốn lặp lại nội dung của hàm get nhưng cần một vài thay đổi. Biểu mẫu giờ đây đã có sẵn từ get_queryset với self.form.

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 
    # ... 
+0

Hoàn hảo! Tôi đã phải trao đổi thứ tự thừa kế (ListView, FormMixin) để giữ cho phân trang hoạt động. – laffuste

+0

Điều này là tốt đẹp nhưng những gì tôi nên sử dụng trong mẫu để xuất tất cả các hình thức. Tôi chỉ thấy một thể hiện của biểu mẫu là phần tử đầu tiên và object_list là danh sách mô hình. –

+4

Bạn có thể liệt kê mã mẫu không? –

0

Từ câu trả lời trước, đây là quan điểm của tôi về quan điểm tôi đã sử dụng để hiển thị các hình thức trên cùng một trang như ListView:

class IndexView(FormMixin, ListView): 
    ''' Homepage: displays list of links, and a form used to create them ''' 
    template_name = "links/index.html" 
    context_object_name = "links" 
    form_class = LinkForm 

    def get_queryset(self): 
     return Links.objects.all() 

def add_link(request): 
    # Sole job of this function is to process the form when POSTed. 
    if request.method == "POST": 
     form = LinkForm(request.POST) 

     if form.is_valid(): 
      Links.objects.create(address=form.cleaned_data['address']) 

     return HttpResponseRedirect('/') 

Sau đó, điều cuối cùng là để ràng buộc add_link xem chức năng đến url hành động của biểu mẫu, và bạn tốt để đi tôi nghĩ.

Các vấn đề liên quan