Serotonin Storm

source>frontendadmin>views.py
  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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# -*- coding: utf-8 -*-

from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.db.models import get_model
from django.forms.models import modelform_factory
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from django.utils.translation import ugettext
from django.views.decorators.cache import never_cache
from django.conf import settings

from frontendadmin.forms import DeleteRequestForm, FrontendAdminModelForm

EXCLUDE = getattr(settings, 'FRONTEND_EXCLUDE', {})
FIELDS = getattr(settings, 'FRONTEND_FIELDS', {})

def check_permission(request, mode_name, app_label, model_name):
    '''
    Check for proper permissions. mode_name may be either add, change or delete.
    '''
    p = '%s.%s_%s' % (app_label, mode_name, model_name)
    return request.user.has_perm(p)

def _get_instance(request, mode_name, app_label, model_name, instance_id=None,
                                            form=FrontendAdminModelForm,
                                            form_fields=None,
                                            form_exclude=None):
    '''
    Returns the model and an instance_form for the given arguments. If an primary
    key (instance_id) is given, it will return also the instance.

    If the user has no permission to add, change or delete the object, a
    HttpResponse is returned.
    '''
    # Check for permission to add/change/delete this object
    if not check_permission(request, mode_name, app_label, model_name):
        return HttpResponseForbidden('You have no permission to do this!')

    try:
        model = get_model(app_label, model_name)
        # get form for model
        if '%s.%s' % (app_label, model_name) in EXCLUDE:
            form_exclude = EXCLUDE['%s.%s' % (app_label, model_name)]
        if '%s.%s' % (app_label, model_name) in FIELDS:
            form_fields = FIELDS['%s.%s' % (app_label, model_name)]
        instance_form = modelform_factory(model, form=FrontendAdminModelForm,
                                          fields=form_fields, exclude=form_exclude)
        # if instance_id is set, grab this model object
        if instance_id:
            instance = model.objects.get(pk=instance_id)
            return model, instance_form, instance
        return model, instance_form
    # Model does not exist
    except AttributeError:
        return HttpResponseForbidden('This model does not exist!')

def _handle_cancel(request, instance=None):
    '''
    Handles clicks on the 'Cancel' button in forms. Returns a redirect to the
    last page, the user came from. If not given, to the detail-view of
    the object. Last fallback is a redirect to the common success page.
    '''
    if request.POST.get('_cancel', False):
        if request.GET.get('next', False):
            return HttpResponseRedirect(request.GET.get('next'))
        if instance and hasattr(instance, 'get_absolute_url'):
            return HttpResponseRedirect(instance.get_absolute_url())
        return HttpResponseRedirect(reverse('frontendadmin_success'))
    return None

def _handle_repsonse(request, instance=None):
    '''
    Handles redirects for completet form actions. Returns a redirect to the
    last page, the user came from. If not given, to the detail-view of
    the object. Last fallback is a redirect to the common success page.
    '''
    if request.GET.get('next', False):
        return HttpResponseRedirect(request.GET.get('next'))
    if instance and hasattr(instance, 'get_absolute_url'):
        return HttpResponseRedirect(instance.get_absolute_url())
    return HttpResponseRedirect(reverse('frontendadmin_success'))

def _get_template(request, template_name, ajax_template_name):
    '''
    Returns wether the ajax or the normal (full html blown) template.
    '''
    try:
        if request.META['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest':
            return ajax_template_name
    except KeyError:
        pass
    return template_name

@never_cache
@login_required
def add(request, app_label, model_name, mode_name='add',
                            template_name='frontendadmin/form.html',
                            ajax_template_name='frontendadmin/form_ajax.html',
                            form_fields=None,
                            form_exclude=None):

    # Get model, instance_form and instance for arguments
    instance_return = _get_instance(request, mode_name, app_label, model_name,
                                                                   form_fields=form_fields,
                                                                   form_exclude=form_exclude)
    if isinstance(instance_return, HttpResponseForbidden):
        return instance_return
    model, instance_form = instance_return

    # Handle cancel request
    cancel = _handle_cancel(request)
    if cancel:
        return cancel

    if request.method == 'POST':
        form = instance_form(request.POST, request.FILES)
        if form.is_valid():
            instance = form.save()
            # Give the user a nice message
            request.user.message_set.create(
                message=ugettext(u'Your %(model_name)s was added successfully' % \
                    {'model_name': model._meta.verbose_name}))
            # Return to last page
            return _handle_repsonse(request, instance)
    else:
        form = instance_form()

    template_context = {
        'action': 'add',
        'action_url': request.build_absolute_uri(),
        'model_title': model._meta.verbose_name,
        'form': form,
    }

    return render_to_response(
        _get_template(request, template_name, ajax_template_name),
        template_context,
        RequestContext(request)
    )

@never_cache
@login_required
def change(request, app_label, model_name, instance_id, mode_name='change',
                                           template_name='frontendadmin/form.html',
                                           ajax_template_name='frontendadmin/form_ajax.html',
                                           form_fields=None,
                                           form_exclude=None):

    # Get model, instance_form and instance for arguments
    instance_return = _get_instance(request, mode_name, app_label, model_name,
                                                           instance_id,
                                                           form_fields=form_fields,
                                                           form_exclude=form_exclude)
    if isinstance(instance_return, HttpResponseForbidden):
        return instance_return
    model, instance_form, instance = instance_return

    # Handle cancel request
    cancel = _handle_cancel(request)
    if cancel:
        return cancel

    if request.method == 'POST':
        form = instance_form(request.POST, request.FILES, instance=instance)
        if form.is_valid():
            instance = form.save()
            # Give the user a nice message
            request.user.message_set.create(
                message=ugettext(u'Your %(model_name)s was changed successfully' % \
                    {'model_name': model._meta.verbose_name}))
            # Return to success page
            return _handle_repsonse(request)
    else:
        form = instance_form(instance=instance)

    template_context = {
        'action': 'change',
        'action_url': request.build_absolute_uri(),
        'model_title': model._meta.verbose_name,
        'form': form,
    }

    return render_to_response(
        _get_template(request, template_name, ajax_template_name),
        template_context,
        RequestContext(request)
    )


@never_cache
@login_required
def delete(request, app_label, model_name, instance_id, mod_name='delete',
                               template_name='frontendadmin/form.html',
                               ajax_template_name='frontendadmin/form_ajax.html',
                               delete_form=DeleteRequestForm):

    # Get model, instance_form and instance for arguments
    instance_return = _get_instance(request, mod_name, app_label, model_name, instance_id)
    if isinstance(instance_return, HttpResponseForbidden):
        return instance_return
    model, instance_form, instance = instance_return

    # Handle cancel request
    cancel = _handle_cancel(request)
    if cancel:
        return cancel

    if request.method == 'POST':
        form = delete_form(request.POST)
        if form.is_valid():
            instance.delete()
            # Give the user a nice message
            request.user.message_set.create(
                message=ugettext(u'Your %(model_name)s was deleted.' % \
                    {'model_name': model._meta.verbose_name}))
            # Return to last page
            return HttpResponseRedirect(reverse('frontendadmin_success_delete'))
    else:
        form = delete_form()

    template_context = {
        'action': 'delete',
        'action_url': request.build_absolute_uri(),
        'model_title': model._meta.verbose_name,
        'form': form,
    }

    return render_to_response(
        _get_template(request, template_name, ajax_template_name),
        template_context,
        RequestContext(request)
    )

def success(request, template_name='frontendadmin/success.html'):
    '''
    First, a view would redirect to the last page the user came from. If
    this is not available (because somebody fiddled in the url), we redirect
    to this common success page.

    Normally a user should never see this page.
    '''
    return render_to_response(template_name, {}, RequestContext(request))

def success_delete(request, template_name='frontendadmin/success_delete.html'):
    '''
    Normally a view would redirect to the last page. After delete from a object
    in a detail-view, there is no "last page" so we redirect to a unique, shiny
    success-page.
    '''
    return render_to_response(template_name, {}, RequestContext(request))