Skip to main content

Django application for smarter application building.

Project description

Django application for smarter CRUD-based applications building.

Overview

Well, it’s mostly about CRUD-based applications - create, read, update and delete different objects, but is not limited to that. If you want admin-like application, but you need a full control on source, than django-smarter may fit your needs.

Installation

Requirements:
  • Django >= 1.3

To install:

pip install django-smarter

Then add smarter to your INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'smarter',
    ...
)

Getting started

Create your models

Let’s define a simple model:

class Page(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField

    def __unicode__(self):
        return self.title

Create generic views

Now you can create generic views for the model.

In your urls.py:

from smarter import SmarterSite
from myapp.models import Page

site = SmarterSite()
site.register(Page)

urlpatterns = patterns('',
    url(r'^', include(site.urls)),

    # other urls ...
)

This will create generic views for Page model, accessed by urls:

  • /page/

  • /page/add/

  • /page/<pk>/

  • /page/<pk>/edit/

  • /page/<pk>/remove/

Customize templates

Each url is mapped to view method and templates.

Templates by urls:

  • /page/ => myapp/page_index.html

  • /page/add/ => myapp/page_add.html

  • /page/<pk>/ => myapp/page_details.html

  • /page/<pk>/edit/ => myapp/page_edit.html

  • /page/<pk>/remove/ => myapp/page_remove.html

Index template has template variable objects_list.

All other templates have variable obj.

Edit and add templates have also template variable form.

Override views

You can subclass views class and add new view methods or override existing ones.

from django.shortcuts import get_object_or_404
from smarter.views import GenericViews
from myapp.models import Page

class PageViews(GenericViews):
    model = Page

    def urls_custom(self):
        return [
            self.url(r'^(?P<pk>\d+)/bookmark/$', 'bookmark')
        ]

    def bookmark_view(self, request, pk):
        obj = get_object_or_404(page, pk=pk)
        # do some stuff for bookmarking ...
        context = {'obj': obj}
        # will render to myapp/page_bookmark.html
        return self.render_to_response(context)

Than you need to register custom views in urls.py:

from smarter import SmarterSite
from myapp.views import PageViews

site = SmarterSite()
site.register(PageViews)

urlpatterns = patterns('',
    url(r'^', include(site.urls)),

    # other urls ...
)

Applying decorators

Assume, you’d like to add login_required decorator to views in your project. You may subclass from GenericViews and use method_decorator helper for that.

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from smarter.views import GenericViews

class Views(GenericViews):

    @method_decorator(login_required)
    def add_view(self, *args, **kwargs):
        return super(Views, self).add_view(*args, **kwargs)

Checking permissions

There’s a special method check_permissions which is invoked from generic views.

It receives keyword arguments depending on processed view:

  • for add action no extra arguments is passed, but if you define form_params_add() result will be passed as keyword arguments

  • for edit action instance argument is passed, actually form_params_edit() result is passed

  • for details and remove actions obj argument is passed

from django.core.exceptions import PermissionDenied
from smarter.views import GenericViews

class Views(GenericViews):

    def check_permissions(self, **kwargs):
        if self.action == 'add':
            if not self.request.is_superuser:
                raise PermissionDenied

        if self.action == 'edit':
            obj = kwargs['instance']
            if obj.owner != self.request.user:
                raise PermissionDenied

Hooks

What if you don’t want to use YourModel.objects.all()? What if you want to call a function or send a signal every time someone visits a certain object’s detail page?

If it’s a small change or addition, you can use the following hooks:

  • get_objects_list(self, action), which returns a queryset. It’s used directly by index_view, and indirectly by the other views, because get_object depends on it (read below). The default implementation just returns self.model.objects.all()

  • get_object(self, pk), which will be used to get the object for remove_view, details_view and edit_view. The default implementation just returns self.get_objects_list().get(pk=pk) or raises Http404.

  • remove_object(self, obj), which deletes the object. The default implementation calls obj.delete().

  • save_form(self, action, **kwargs) saves the form in both the edit and add views.

  • get_form(self, form): in this method, you return a form for the edit and add view. It’s usually a ModelForm, but you can provide a form instance with a save() method, or hook into save_form. The default implementation gets a form from the self.form_class dict, otherwise creates a ModelForm using modelform_factory.

Don’t forget you can get the current request through self.request, and the current action (E.G. 'index' or details) is available in self.action.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-smarter-0.4.1.tar.gz (7.5 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page