123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- # -*- coding: utf-8 -*-
- from django.conf import settings
- from django.contrib.contenttypes.models import ContentType
- from django.shortcuts import get_object_or_404, redirect
- from django.views import generic
- from django.core.exceptions import PermissionDenied
- from django.template import RequestContext
- from django.utils.http import urlquote_plus
- from django.template import loader
- from django.http import HttpResponse
- from rapid.models import DocumentTemplate
- from rapid.officedocs.rtf import RtfTemplate
- from rapid.wrappers import InstanceData, ModelData
- from rapid.filters import FilterSet
- from rapidforms import for_model
- import math
- from os import path
- def _build_uri(request, params):
- param_string = "&".join(["%s=%s" % (urlquote_plus(k), urlquote_plus(params[k])) for k in params.keys()])
- base = request.build_absolute_uri().split("?")[0]
- return base + "?" + param_string
- def _copy_dict(dc):
- d = {}
- for k in dc.keys():
- d[k] = dc[k]
- return d
- def _replace_param(request, param_name, param_value):
- get = _copy_dict(request.GET)
- get[param_name] = param_value
- return _build_uri(request, get)
- def is_ajax_request(request):
- # X-Requested-With: XMLHttpRequest
- w = request.META.get('HTTP_X_REQUESTED_WITH')
- if w:
- return True
- return False
- class ListView(generic.list.ListView):
- template_name = 'rapid/bare/list.html'
- action_name = ''
- registers_per_page = 50
- number_of_edge_pages = 5
- number_of_middle_pages = 5
- fields = None
- class Pagination(object):
- def __init__(self, request, page, number_of_edge_pages, number_of_middle_pages,
- registers_per_page, total_pages):
- self.request = request
- self.number_of_edge_pages = number_of_edge_pages
- self.number_of_middle_pages = number_of_middle_pages
- self.registers_per_page = registers_per_page
- self.page = page
- self.total_pages = total_pages
- def _page_and_uri(self, pages):
- get2 = _copy_dict(self.request.GET)
- for p in pages:
- get2['page'] = p
- yield (p, _build_uri(self.request, get2))
- def start_numbers(self):
- """
- Page numbers listed at the beginning of the pagination area
- """
- e = self.number_of_edge_pages
- for i in range(1, min(e+1, self.page)):
- yield i
- def start(self):
- """
- Page numbers and URLs listed at the beginning of the pagination area
- """
- return self._page_and_uri(self.start_numbers())
- def before_numbers(self):
- """
- Page numbers listed at the pagination area before the current page
- """
- m = self.number_of_middle_pages
- for i in range(max(self.page - m, m), self.page):
- yield i
- def before(self):
- """
- Page numbers and URLs listed at the pagination area before the current page
- """
- return self._page_and_uri(self.before_numbers())
- def after_numbers(self):
- """
- Page numbers listed at the pagination area after the current page
- """
- m = self.number_of_middle_pages
- e = self.number_of_edge_pages
- for i in range(self.page + 1, min(self.page + m + 1, self.total_pages - e + 1)):
- yield i
- def after(self):
- """
- Page numbers and URLs listed at the pagination area after the current page
- """
- return self._page_and_uri(self.after_numbers())
- def end_numbers(self):
- """
- Page numbers listed at the end of the pagination area
- """
- e = self.number_of_edge_pages
- for i in range(max(self.page + 1, self.total_pages - e + 1), self.total_pages + 1):
- yield i
- def end(self):
- """
- Page numbers and URLs listed at the end of the pagination area
- """
- return self._page_and_uri(self.end_numbers())
- def separate_end(self):
- """
- True if there's a separator between the next pages and the end pages.
- """
- return self.page < self.total_pages - self.number_of_edge_pages - self.number_of_middle_pages
- def separate_start(self):
- """
- True if there's a separator between the start pages and the before pages.
- """
- return self.page > self.number_of_edge_pages + self.number_of_middle_pages
- def get_page(self, queryset):
- return queryset[self.registers_per_page*(self.page-1):self.registers_per_page*self.page]
- class View(object):
- order_param = 'order'
- def __init__(self, request, action_name, model, queryset, fields, pagination):
- self.request = request
- self.model = model
- self.action_name = action_name
- self._fields = fields
- q = queryset
- self.filters = FilterSet.from_request(ModelData(self.model), request)
- if self.filters:
- q = q.filter(**self.filters.query_dict())
- self.queryset = q
- total = q.count()
- pagination.total_pages = int(math.ceil(total / pagination.registers_per_page))
- order = request.GET.get(self.order_param)
- if order:
- q = q.order_by(order)
- self.queryset = pagination.get_page(q)
- def values(self):
- for o in self.queryset:
- if self._fields:
- c = InstanceData(o, request=self.request, fields=self._fields)
- else:
- c = InstanceData(o, request=self.request)
- if c.has_permission(self.request, self.action_name):
- yield c
- def fields(self):
- order_param = self.order_param
- request = self.request
- class FieldParams(object):
- def __init__(self, field):
- self.field = field
- def order_up_url(self):
- return _replace_param(request, order_param, self.field.bare_name())
- def order_down_url(self):
- return _replace_param(request, order_param, u'-' + self.field.bare_name())
- def add_filter_url(self):
- pass
- def del_filter_url(self):
- pass
- for f in ModelData(self.model, request=self.request, fields=self._fields).fields():
- f.view = FieldParams(f)
- yield f
- def get(self, request, **kwargs):
- mdt = ModelData(self.model, request)
- if not mdt.has_permission(request, self.action_name):
- raise PermissionDenied
- object_list = self.get_queryset()
- # Populates the context
- context = RequestContext(request).flatten()
- context.update(kwargs)
- total_pages = int(math.ceil(object_list.count() / self.registers_per_page))
- page = int(request.GET.get('page', 1))
- p = self.Pagination(request, page, self.number_of_edge_pages,
- self.number_of_middle_pages, self.registers_per_page,
- total_pages)
- context['pages'] = p
- context['model'] = ModelData(self.model, request, fields=self.fields)
- context['view'] = self.View(request, self.action_name, self.model, object_list, self.fields, p)
- offset = (page - 1) * self.registers_per_page
- self.object_list = object_list[offset: offset + self.registers_per_page]
- context[self.get_context_object_name(object_list)] = object_list
- context['object_list'] = object_list
- context = self.get_context_data(**context)
- # noinspection PyAttributeOutsideInit
- self.object_list = object_list
- return self.render_to_response(context)
- class ReadView(generic.detail.DetailView):
- template_name = 'rapid/bare/detail.html'
- action_name = ''
- request = None
- def get_object(self, request=None):
- return get_object_or_404(self.model, pk=self.kwargs['pk'])
- # noinspection PyMethodOverriding
- def get(self, request, pk, **kwargs):
- context = RequestContext(request).flatten()
- context.update(kwargs)
- obj = self.get_object(self.request)
- context['object'] = obj
- context[self.get_context_object_name(obj)] = obj
- cd = InstanceData(obj, request=request)
- if not cd.has_permission(request, self.action_name):
- raise PermissionDenied
- excludes = request.GET.get('exclude')
- if excludes:
- cd.excludes = excludes.split(",")
- # noinspection PyAttributeOutsideInit
- self.object = cd
- context['object_data'] = cd
- context = self.get_context_data(**context)
- return self.render_to_response(context)
- class CreateView(generic.edit.CreateView):
- template_name = 'rapid/bare/create.html'
- action_name = ''
- object = None
- fields = '__all__'
- def request_form(self, request):
- return for_model(request, self.model)
- def get(self, request, **kwargs):
- context = RequestContext(request).flatten()
- context.update(kwargs)
- cd = ModelData(self.model, request=request)
- if not cd.has_permission(request, self.action_name):
- raise PermissionDenied
- context['model_data'] = cd
- if request.POST:
- context['form'] = self.request_form(request)(request.POST, request.FILES)
- else:
- context['form'] = self.request_form(request)()
- context = self.get_context_data(**context)
- return self.render_to_response(context)
- def post(self, request, **kwargs):
- m = ModelData(self.model, request=request)
- if m.has_permission(request, self.action_name):
- f = self.request_form(request)(request.POST, request.FILES)
- if f.is_valid():
- f.save()
- return redirect(m.list_url())
- return self.get(request, **kwargs)
- raise PermissionDenied()
- class UpdateView(generic.edit.UpdateView):
- template_name = 'rapid/bare/update.html'
- action_name = ''
- fields = '__all__'
- def get_object(self, queryset=None):
- return get_object_or_404(self.model, pk=self.kwargs['pk'])
- def request_form(self, request):
- return for_model(request, self.model)
- # noinspection PyMethodOverriding
- def get(self, request, pk, **kwargs):
- context = RequestContext(request).flatten()
- context.update(kwargs)
- obj = self.get_object()
- context['object'] = obj
- context[self.get_context_object_name(obj)] = obj
- cd = InstanceData(obj, request=request)
- if not cd.has_permission(request, self.action_name):
- raise PermissionDenied
- # noinspection PyAttributeOutsideInit
- self.object = cd
- context['object_data'] = cd
- if request.POST:
- context['form'] = self.request_form(request)(request.POST, request.FILES, instance=obj)
- else:
- context['form'] = self.request_form(request)(instance=obj)
- context = self.get_context_data(**context)
- return self.render_to_response(context)
- # noinspection PyMethodOverriding,PyAttributeOutsideInit
- def post(self, request, pk, **kwargs):
- obj = self.get_object()
- m = InstanceData(obj, request=request)
- if m.has_permission(request, self.action_name):
- f = self.request_form(request)(request.POST, request.FILES, instance=obj)
- if f.is_valid():
- if f.instance.pk != obj.pk:
- raise PermissionDenied
- f.save()
- return redirect(m.list_url())
- self.form = f
- return self.get(request, pk, **kwargs)
- raise PermissionDenied
- class DeleteView(generic.edit.DeleteView):
- template_name = 'rapid/bare/delete.html'
- action_name = ''
- fields = '__all__'
- def __init__(self, **kwargs):
- super(DeleteView, self).__init__(**kwargs)
- self.success_url = ModelData(self.model).list_url()
- def get_object(self, queryset=None):
- return get_object_or_404(self.model, pk=self.kwargs['pk'])
- def has_permission(self, request, instance):
- return instance.has_permission(request, self.action_name)
- def get(self, request, *args, **kwargs):
- obj = InstanceData(self.get_object())
- if not self.has_permission(request, obj):
- raise PermissionDenied
- return super(DeleteView, self).get(request, *args, **kwargs)
- def post(self, request, *args, **kwargs):
- obj = InstanceData(self.get_object())
- if not self.has_permission(request, obj):
- raise PermissionDenied
- return super(DeleteView, self).post(request, *args, **kwargs)
- class SelectView(ListView):
- """
- A selectable list of objects.
- """
- template_name = 'rapid/bare/select.html'
- def bare_or_main(view):
- main_window_template = "rapid/main_window.html"
- def vw(request, *args, **kwargs):
- resp = view(request, *args, **kwargs)
- bare = is_ajax_request(request)
- if bare:
- if 300 <= resp.status_code <= 399:
- # I'll interpret redirects as successful POST,
- # thus, the response'll get replaced by something with
- # a header that says "success!"
- ret = HttpResponse('')
- ret['X-FORM-STATUS:'] = 'success'
- return ret
- if not bare and resp.status_code == 200 and request.method != "HEAD":
- if hasattr(resp, 'render'):
- resp.render()
- body = resp.content
- main_win = loader.get_template(main_window_template)
- context = RequestContext(request)
- context.update({'body_text': body, 'this_url': request.get_full_path()})
- resp.content = main_win.render(context, request)
- return resp
- return vw
- def update_form_class(form):
- class F(UpdateView):
- def request_form(self, request):
- return form
- return F
- def add_form_class(form):
- class F(CreateView):
- def request_form(self, request):
- return form
- return F
- class RenderDocumentView(generic.View):
- model = None
- action_name = None
- # noinspection PyUnusedLocal
- def get(self, request, pk, template):
- inst = get_object_or_404(self.model, pk=pk)
- ctx = inst.__dict__
- tm = get_object_or_404(DocumentTemplate, model=ContentType.objects.get_for_model(self.model), pk=template)
- f = path.join(settings.MEDIA_ROOT, tm.template.name)
- t = RtfTemplate(f, ctx)
- return HttpResponse(t.read(), content_type='application/rtf')
- def get_delete_document_template_view(model):
- class DeleteDocumentTemplateView(DeleteView):
- def get_object(self, queryset=None):
- return get_object_or_404(DocumentTemplate, pk=self.kwargs['pk'])
- def has_permission(self, request, instance):
- if not ModelData(model).has_permission(request, self.action_name):
- return False
- return instance.instance.model == ContentType.objects.get_for_model(model)
- return DeleteDocumentTemplateView
|