## 12.5 模式5:可重用的搜索混合(Mixin)视图


    在这个例子中,我们将要覆盖到如何在对应两个不同模型的两个视图中重用一个搜索表单。

    假设两个模型都有一个title字段(此模式也会证明为什么在项目中使用命名标准是一个好的事情)。这个例子将会证明,在Flavor和IceCreamStore模型中,一个单一的CBV也能用来提供简单的搜索功能。

    我们通过在我们的视图中创建一个简单的搜索Mixin开始:

    1. EXMAPLE 12.13
    2. # core/views.py
    3. class TitleSearchMixin(object):
    4. def get_queryset(self):
    5. # Fetch the queryset from the parent's get_queryset
    6. queryset = super(TitleSearchMixin, self).get_queryset()
    7. # Get the q GET parameter
    8. q = self.request.GET.get("q")
    9. if q:
    10. # return a filtered queryset
    11. return queryset.filter(title__icontains=q)
    12. # No q is specified so we return queryset
    13. return queryset

    上面代码你应该十分熟悉,因为我们几乎一字不差的使用在Forms + View例子中。下面是如何在Flavor和IceCreamStore视图中使用,首先是Flavor视图:

    1. EXAMPLE 12.14
    2. # add to flavors/views.py
    3. from django.views.generic import ListView
    4. from core.views import TitleSearchMixin
    5. from .models import Flavor
    6. class FlavorListView(TitleSearchMixin, ListView):
    7. model = Flavor

    添加到冰淇淋商店视图:

    1. EXAMPLE 12.15
    2. # add to stores/views.py
    3. from django.views.generic import ListView
    4. from core.views import TitleSearchMixin
    5. from .models import Store
    6. class IceCreamStoreListView(TitleSearchMixin, ListView):
    7. model = Store

    至于表单?我们仅仅对每个ListView在HTML定义:

    1. EXAMPLE 12.16
    2. {# form to go into stores/store_list.html template #}
    3. <form action="" method="GET">
    4. <input type="text" name="q" />
    5. <button type="submit">search</button>
    6. </form>

    1. EXAMPLE 12.17
    2. {# form to go into flavors/flavor_list.html template #}
    3. <form action="" method="GET">
    4. <input type="text" name="q" />
    5. <button type="submit">search</button>
    6. </form>

    现在我们在两个视图中有了相同的Mixin。Mixins是一个很好的方式来重用代码,但是在单一的类中使用太多Mixin将会导致难以维护代码。像一如既往那样,尽可能保证你的代码简单明了。