CRUD or create, read, update, and delete are the four basic functions on Django Model. Viewflow provides ready-to-use CRUD viewsets, views, and templates based on google material design. Combined all together they allow to implement Django admin like functionality.
You can quickly instantiate a Viewset by passing required parameters to a class constructor
from viewflow import Icon
from viewflow.urls import ReadonlyModelViewset, ModelViewset
categories_viewset = ReadonlyModelViewset(
app_name='category',
icon=Icon('category'),
model=models.Category,
list_view=views.custom_list_view,
)
Or inherit from a viewset class and override methods and attributes
class DepartmentViewset(ModelViewset):
icon = Icon('people')
model = models.Department
list_columns = ('name', 'manager', 'parent')
list_filter_fields = ('parent', )
After inclusion into an Application viewset, you will get a model list page with links points to model details or edit pages.
ModelViewset
is the viewset that mixes list model view
with create/update views. Use DetailViewMixin
to point
links from list view to model detail page, before change form.
DetailViewMixin
adds ability to delete a model instance.
ReadonlyModelViewset
only list a model and provide model
details page.
The only mandatory option for CRUD viewsets is the model class. You would also like to customize icon and title appearance in the site menu.
To optimize querying or restrict models listed, specify queryset attribute or override get_queryset method.
class EmployeeViewset(DetailViewMixin, ModelViewset):
model = models.Employee
queryset = model._default_manager.select_related('department')
def get_queryset(self, request);
if not request.user.is_staff:
return self.queryset.exclude(department__parent_isnull=True)
return self.queryset
You can replace a build-in view with our own functional or class-based view. Or pass additional keyword parameters to .as_view call
list_view_class = views.EmployeeListView
create_view = views.create_employee_view
def get_update_view_kwargs(self):
return {
'success_url': reverse('emp:employee:index')
}
As for any viewset, you can add additional views, just by adding an attribute named with _url suffix
manager_change_url = path(
'<path:pk>/manages/', views.change_manager, name='change_manager'
)
TODO
Set list_columns to control which fields are displayed on the change list view.
If you don’t set list_columns, the list view will display a single column that with __str__() representation of each object.
There are three types of values that can be used in list_display:
The name of a model field. For example:
class EmployeeViewset(ModelViewset):
list_columns = ('first_name', 'last_name')
A string representing a Viewset method that accepts one argument, the model instance. For example:
class EmployeeViewset(ModelViewset):
list_columns = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
Or a string representing a model attribute or method (without any required arguments)
Use list_object_link_columns to control if and which fields in list_display should be linked to the “change” or “detail” page for an object.
TODO
TODO list_filter_class list_filter_fields
Viewflow CRUd viewsets check standard Django add/change/delete/view user per-object permissions. Unlike default django behavior, if user have no-object specific permission, for example if user.has_perm(‘myapp.change_employee’, obj=None) equals True, default viewflow behavior is to assume that user have the permission for all objects. on if has_perm with obj=None return False object specific permission is checked. You can override in corresponding has_view_permission, has_add_permission, has_change_permission, has_delete_permission methods.
def has_delete_permission(self, request, obj=None):
return request.user.is_staff
Pre-built views for admin like interfaces. All viewflow.views are inherited from core Django generic views with very few additions and method redefinitions.
All of them are accepts viewset as keyword parameter for the .as_view() method. If viewset present, the viewset methods and options would be used, permission checking methods like has_add_permission need to be overridden only in a viewset, and they would be used by a view. Same for get_queryset method.