1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
|travis| |codecov|
django-extra-views - The missing class-based generic views for Django
========================================================================
Django's class-based generic views are great, they let you accomplish a large number of web application design patterns in relatively few lines of code. They do have their limits though, and that's what this library of views aims to overcome.
.. |travis| image:: https://secure.travis-ci.org/AndrewIngram/django-extra-views.svg?branch=master
:target: https://travis-ci.org/AndrewIngram/django-extra-views
.. |codecov| image:: https://codecov.io/github/AndrewIngram/django-extra-views/coverage.svg?branch=master
:target: https://codecov.io/github/AndrewIngram/django-extra-views?branch=master
Installation
------------
Installing from pypi (using pip). ::
pip install django-extra-views
Installing from github. ::
pip install -e git://github.com/AndrewIngram/django-extra-views.git#egg=django-extra-views
See the `documentation here`_
.. _documentation here: https://django-extra-views.readthedocs.org/en/latest/
Features so far
------------------
- FormSet and ModelFormSet views - The formset equivalents of FormView and ModelFormView.
- InlineFormSetView - Lets you edit formsets related to a model (uses inlineformset_factory)
- CreateWithInlinesView and UpdateWithInlinesView - Lets you edit a model and its relations
- GenericInlineFormSetView, the equivalent of InlineFormSetView but for GenericForeignKeys
- Support for generic inlines in CreateWithInlinesView and UpdateWithInlinesView
- Support for naming each inline or formset with NamedFormsetsMixin
- SortableListMixin - Generic mixin for sorting functionality in your views
- SearchableListMixin - Generic mixin for search functionality in your views
Still to do
-----------
I'd like to add support for pagination in ModelFormSetView and its derivatives, the goal being to be able to mimic the change_list view in Django's admin. Currently this is proving difficult because of how Django's MultipleObjectMixin handles pagination.
Examples
--------
Defining a FormSetView.
.. code-block:: python
from extra_views import FormSetView
class AddressFormSet(FormSetView):
form_class = AddressForm
template_name = 'address_formset.html'
Defining a ModelFormSetView.
.. code-block:: python
from extra_views import ModelFormSetView
class ItemFormSetView(ModelFormSetView):
model = Item
template_name = 'item_formset.html'
fields = '__all__'
Defining a CreateWithInlinesView and an UpdateWithInlinesView.
.. code-block:: python
from extra_views import CreateWithInlinesView, UpdateWithInlinesView, InlineFormSetFactory
from extra_views.generic import GenericInlineFormSetFactory
class ItemInline(InlineFormSetFactory):
model = Item
fields = '__all__'
class TagInline(GenericInlineFormSetFactory):
model = Tag
fields = '__all__'
class CreateOrderView(CreateWithInlinesView):
model = Order
inlines = [ItemInline, TagInline]
fields = '__all__'
class UpdateOrderView(UpdateWithInlinesView):
model = Order
inlines = [ItemInline, TagInline]
fields = '__all__'
# Example URLs.
urlpatterns = [
url(r'^orders/new/$', CreateOrderView.as_view()),
url(r'^orders/(?P<pk>\d+)/$', UpdateOrderView.as_view()),
]
Other bits of functionality
---------------------------
If you want more control over the names of your formsets (as opposed to iterating over inlines), you can use NamedFormsetsMixin.
.. code-block:: python
from extra_views import NamedFormsetsMixin
class CreateOrderView(NamedFormsetsMixin, CreateWithInlinesView):
model = Order
inlines = [ItemInline, TagInline]
inlines_names = ['Items', 'Tags']
fields = '__all__'
You can add search functionality to your ListViews by adding SearchableMixin and by setting search_fields:
.. code-block:: python
from django.views.generic import ListView
from extra_views import SearchableListMixin
class SearchableItemListView(SearchableListMixin, ListView):
template_name = 'extra_views/item_list.html'
search_fields = ['name', 'sku']
model = Item
In this case ``object_list`` will be filtered if the 'q' query string is provided (like /searchable/?q=query), or you
can manually override ``get_search_query`` method, to define your own search functionality.
Also you can define some items in ``search_fields`` as tuple (e.g. ``[('name', 'iexact', ), 'sku']``)
to provide custom lookups for searching. Default lookup is ``icontains``. We strongly recommend to use only
string lookups, when number fields will convert to strings before comparison to prevent converting errors.
This controlled by ``check_lookups`` setting of SearchableMixin.
Define sorting in view.
.. code-block:: python
from django.views.generic import ListView
from extra_views import SortableListMixin
class SortableItemListView(SortableListMixin, ListView):
sort_fields_aliases = [('name', 'by_name'), ('id', 'by_id'), ]
model = Item
You can hide real field names in query string by define sort_fields_aliases attribute (see example)
or show they as is by define sort_fields. SortableListMixin adds ``sort_helper`` variable of SortHelper class,
then in template you can use helper functions: ``{{ sort_helper.get_sort_query_by_FOO }}``,
``{{ sort_helper.get_sort_query_by_FOO_asc }}``, ``{{ sort_helper.get_sort_query_by_FOO_desc }}`` and
``{{ sort_helper.is_sorted_by_FOO }}``
More descriptive examples to come.
|