2017 OOAO DRY BUZZWORDS FOR DJANGO 2.0 with Material design
Project description
CRUDLFA+ stands for Create Read Update Delete List Form Autocomplete and more.
This package provides a more DRY way to rapidely develop modern web applications by thinking differently:
Composition over inheritance with an intermediary layer to use in urls.py,
JavaScript is a first class citizen,
Integration with external Django apps more than welcome,
Consider this as a brand new framework with a lot of modern features, except you don’t have to learn a new framework because this is still Django, with a 2017 feels.
Try
This should start the example project in src/crudlfap_example where each documented example lives:
pip install --user crudlflap[django,tables2,filter,dal,reversion,debug]; crudlfap runserver
Install
To add crudlfap to your project, first copy over settings from crudlfap_example.settings.TEMPLATES or enable jinja2 manually. Also set LOGIN_REDIRECT_URL = '/' for now.
Then add crudlfap to your settings.INSTALLED_APPS. You can find other crudlfap apps you can add with the following commmand:
echo 'from django.conf import settings; settings.INSTALLED_APPS' | crudlfap shell | grep crud
You will also need a context processor that sets the base template context, ie. crudlfap.context_processors.base, but then again, just copy over the TEMPLATES .
Examples
Let’s hack a modern CRUD for your Server model where you can override default templates, add this to your app’s urls.py:
from crudlfap import crudlfap
from .models import Server
# Use fields='__all__' to allow read/write on all model fields for
# everybody for now, also show Server Router views in main menu
urlpatterns = crudlfap.Router(Server, fields='__all__', menus=['main']).urlpatterns()
Then, add it to your project’s urls.py:
urlpatterns = [
url(r'^yourapp/', include('yourapp.urls')), # what you created above
url(r'^crudlfap/', include('crudlfap.urls')), # for debug views
# for auth views, we haz material templates
url(r'^auth/', include('django.contrib.auth.urls')),
url(r'^$', generic.TemplateView.as_view(template_name='crudlfap/home.html')), # for free
# Also, remove django.contrib.admin from ehere and INSTALLED_APPS, not
# that it's not compatible, but CRUDLFA+ provides better features so do
# yourself a favor in 2017 and use CRUDLFA+'s modern router instead
]
Now, open your browser and learn to love CRUDFA+ and look at your material design website. Don’t forget to check the registered url list which was generated for you.
Let’s setup the default queryset per user for views and forms etc and set some permissions on views and fields, all OOAO:
class ServerCreateView(crudlfap.CreateView):
@classmethod
def allow(cls, user):
return True if user.is_authenticated() else False
class ServerOwnerRequired(crudlfap.FormViewMixin):
@classmethod
def allow(cls, user, model):
return user.is_staff or model.owner == user
class ServerUpdateView(ServerOwnerRequired, crudlfap.UpdateView):
pass
class ServerDeleteView(ServerOwnerRequired, crudlfap.UpdateViewView):
pass
class ServerRouter(Router):
menus = ['main'] # Yes Django can make menus
fa_icon = 'server' # Yes with icons
views = [
ServerCreateView,
crudlfap.DetailView,
crudlfap.ListView,
ServerUpdateView,
ServerDeleteView,
]
readable_fields = ['name', 'owner', 'created'] # yes per attr authorization
def get_writable_fields(self, user): # yes per user attr authorization
if request.user.is_staff:
return ['name', 'owner']
else:
return ['name']
# yes django allows OOAO for viewland, and you can invent words too
def get_queryset(self, user):
if not user.pk:
return Server.objects.filter(is_public=True)
if not request.user.is_staff:
return self.model.objects.filter(
Q(is_public=True)|Q(owner=request.user)
)
return self.model.objects.all()
urlpatterns = ServerRouter(Server).urlpatterns()
Example checking security in template (Jinja2):
{% if crulfap_router(object).get_view_by_slug('update').allow(request.user, object) %}
Example checking security in Python:
if crudlfap.routers['yourapp.server']['update'].allow(user, server): # User has permission to update on the default router for yourapp.Server
Now if you want to make your own link to an object update modal because you are in 2017 then you could use this Jinja2 function:
{% cruldfap_modal object 'update' %}
Note that the above won’t render anything if the user doesn’t have the permission to execute the update view.
Now if you want to render a particular model field attribute after checking user permission:
{% if 'created' in crudlfap_router(object).get_writable_fields(request.user) %} {% crudlfap_attribute_label object 'created' %}: {% crudlfap_attribute_value object 'created' %} {% endif %}
Or just:
{% crudlfap_attribute object 'created' %}
Check the default templates for moar 2017 DRY fun !
Now, if you think this pattern is too 2017 for you, wait until we add some custom actions on this model:
from django import forms
from django.contrib import messages
class ServerRefreshView(crudlfap.FormView):
menus = ['object_actions'] # show in detail and list view
fa_icon = 'refresh' # icon for this view / menu links
style = 'warning' # view style variable
def allow(self, user, model=None):
return model.is_public or model.owner == user
def form_valid(self, form):
try:
self.object.refresh_from_your_cloud()
except YourCloudException as e:
if self.request.user.is_staff:
messages.error(unicode(e))
else:
messages.error(_('Server {} refresh fail').format(self.object))
logger.exception('Failed to refresh server')
else:
messages.success(_('Server {} refreshed').format(self.object))
return self.object.get_absolute_url()
class ServerRouter(crudlfap.Router):
views = [
ServerCreateView,
crudlfap.DetailView,
crudlfap.ListView,
ServerUpdateView,
ServerDeleteView,
ServerRefreshView,
]
urlpatterns = ServerRouter(Server).urlpatterns()
Refresh your browser and you will see a new “refresh” button with the ‘fa-refresh’ icon in the list view and the detail view
Ok so you want to integrate django-reversion and django-tables2 then please dear knock yourself out:
class ServerRouter(crudlfap.Router):
views = [
ServerCreateView,
# yes you can haz type() on the fly
dict(_cls='crudlfap.DetailView', fields=['name']),
'crudlfap.Tables2ListView',
'crudlfap.ReversionView',
ServerUpdateView,
ServerDeleteView,
ServerRefreshView,
]
urlpatterns = ServerRouter(Server).urlpatterns()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.