# -*- coding: utf-8 -*- from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.core.context_processors import csrf from django.core.urlresolvers import reverse_lazy from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.admin.views.decorators import staff_member_required from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage, InvalidPage from django.db.models.deletion import ProtectedError from django.utils.translation import ugettext as _ #forms and models from file.forms import FileModelForm from file.models import TmpFile from theme.models import Tag from accounts.models import User from functions.forms import AdminSearchForm from django.utils.translation import get_language as lang from hvad.utils import get_translation_aware_manager #python import random from django.views.generic import ListView as OldListView class ListView(OldListView): """ Default Django generic ListView with few overrided methods for redirecting onto first page of pagination in case of entering big page number(for search engines) List of modules, where overrided ListView is used: - accounts.views - article.views - company.views - conference.views - core.views - exposition.views - photologue.views - place_exposition.views - specialist_catalog.views - translator.views """ def paginate_queryset(self, queryset, page_size): """ Paginate the queryset, if needed. """ paginator = self.get_paginator(queryset, page_size, allow_empty_first_page=self.get_allow_empty()) page_kwarg = self.page_kwarg page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1 try: page_number = int(page) except ValueError: if page == 'last': page_number = paginator.num_pages else: raise Http404(_("Page is not 'last', nor can it be converted to an int.")) try: page = paginator.page(page_number) self.kwargs['home'] = False except EmptyPage as e: page = paginator.page(1) self.kwargs['home'] = True return (paginator, page, page.object_list, page.has_other_pages()) def get(self, request, *args, **kwargs): response = super(ListView, self).get(request, *args, **kwargs) if self.kwargs.get("home"): path = self.request.path return HttpResponseRedirect(path[:path.find('page')]) else: return response @login_required def filtered_list(request, objects, template, item_per_page=settings.ADMIN_PAGINATION): """ Return template with objects in it with pagination item_per_page - how many objects view in the one page """ paginator = Paginator(objects, item_per_page) page = request.GET.get('page') try: objects = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. objects = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. objects = paginator.page(paginator._num_pages) return render_to_response(template, {'objects': objects, 'search_form': AdminSearchForm()}) from django.db.models.loading import get_model from theme.models import Theme @staff_member_required def objects_list(request, Model, template, item_per_page=settings.ADMIN_PAGINATION): """ Return template with all objects of model Model Model - objects Model item_per_page - how many objects view in the one page """ if request.GET: form = AdminSearchForm(request.POST) if form.is_valid(): s_name = request.GET.get('search_name') if s_name: objects = get_translation_aware_manager(Model).filter(name__contains=s_name).distinct() return filtered_list(request, objects, template, 1000) else: list = Model.objects.all() else: list = Model.objects.all() paginator = Paginator(list, item_per_page) page = request.GET.get('page') try: objects = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. objects = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. objects = paginator.page(paginator._num_pages) return render_to_response(template, {'objects': objects, 'search_form': AdminSearchForm()}) @login_required def add_object(request, Form, template_string, redirect_string, #required values choices={}, init_data ={}): if request.POST: form = Form(request.POST) #set choices filled by ajax if 'city' in choices: form.fields['city'].choices = [(item.id, item.name) for item in choices['city'].objects.filter(country=request.POST['country'])] if 'tag' in choices: form.fields['tag'].choices = [(item.id, item.name) for item in choices['tag'].objects.all()] if form.is_valid(): form.save() return HttpResponseRedirect(redirect_string) else: form = Form(initial=init_data) args = {} args.update(csrf(request)) args['languages'] = settings.LANGUAGES args['form'] = form return render_to_response(template_string, args) @login_required def add_object_with_file(request, Form, template, redirect_string, #required values choices={}, init_data ={}): """ Return form and FileForm and post it on the server. Create key which will be check tmp files If form is posted redirect on the page in redirect_string FileForm posts with ajax choices are ... """ #cheks if key already exist(when form wasn't validated) if request.POST.get('key'): key = request.POST['key'] else: key = random.getrandbits(128) #initial FileForm with key for checking if file connected to object file_form = FileModelForm(initial={'key': key}) if request.POST: form = Form(request.POST) #set choices filled by ajax if 'city' in choices: form.fields['city'].choices = [(item.id, item.name) for item in choices['city'].objects.filter(country=request.POST['country'])] if 'tag' in choices: form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.all()] if form.is_valid(): form.save() return HttpResponseRedirect(redirect_string) else: init_data['key'] = key form = Form(initial=init_data) args = {} args.update(csrf(request)) #languages uses in template args['languages'] = settings.LANGUAGES args['form'] = form args['file_form'] = file_form #list of files connected to this form args['files'] = TmpFile.objects.filter(key=key) return render_to_response(template, args) @login_required def delete_object(request, Model, Form, url, prev_page,): """ Form must have 1 parameter url or id """ if request.GET: url = request.GET.get('url') id = request.GET.get('id') if url: object = Model.objects.get(url=url) else: object = Model.objects.get(id=id) try: object.delete() return HttpResponseRedirect(prev_page) except ProtectedError: msg = _(u'Удаления %(object)s требует удаления связаных объектов') % {'object': object} return render_to_response('delete.html', {'msg':msg, 'prev_page':prev_page}) else: try: object = Model.objects.get(url=url) except: object = Model.objects.get(id=url) form = Form(instance=object) args = {} args.update(csrf(request)) args['form'] = form args['object'] = object args['prev_page'] = prev_page return render_to_response('delete.html', args) #-----class------------------ from django.views.generic import DetailView from functions.views_help import split_params from city.models import City from exposition.models import Exposition from conference.models import Conference from seminar.models import Seminar from webinar.models import Webinar from company.models import Company from photoreport.models import Photoreport class ExpoMixin(object): def get_params(self): model_names = {Exposition: _(u'Выставки'), Conference: _(u'Конференции'), Seminar: _(u'Семинары'), Webinar: _(u'Вебинары'), Company: _(u'Участники'), Photoreport: _(u'Фоторепортажи')} model_alternative_name = {Exposition: 'exposition', Conference: 'conference', Photoreport: 'photoreport'} params = [{'type':'model', 'url':self.model, 'name': model_names.get(self.model), 'alternative_name': model_alternative_name.get(self.model)}] st = self.kwargs.get('params') if st: params = params + split_params(st) return params single_page_filter = {Exposition:'event', Conference:'event', Seminar:'event', Webinar:'event', Company:'member', User:'visitor', Photoreport: 'photoreport'} from meta.models import MetaSetting from meta.views import Meta class ExpoListView(ExpoMixin, ListView): """ """ paginate_by = settings.CLIENT_PAGINATION params = None single_page = False search_form = None order = None def get_queryset(self): query = self.model.objects.all() params = self.get_params() for param in params: if param.get('type') == 'country': country = Country.objects.safe_get(url=param.get('url')) if country: param['name'] = country.name query = query.filter(country=country) if param.get('type') == 'city': city = City.objects.safe_get(url=param.get('url')) if city: param['name'] = city.name query = query.filter(city=city) if param.get('type') == 'theme': theme = Theme.objects.safe_get(url=param.get('url')) if theme: param['name'] = theme.name query = query.filter(theme=theme) if param.get('type') == 'tag': tag = Tag.objects.safe_get(url=param.get('url')) if tag: param['name'] = tag.name query = query.filter(tag=tag) if param.get('type') == 'year': param['name'] = param.get('url') query = query.filter(data_begin__year=param.get('url')) if param.get('type') == 'month': monthes = {'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12} param['name'] = param.get('url') query = query.filter(data_begin__month=monthes.get(param.get('url'))) if param.get('type') == 'member' and self.model != Company: param['name'] = param.get('url') company = Company.objects.safe_get(url=param.get('url')) if company: param['name'] = company.name query = query.filter(company__in=[company]) if param.get('type') == single_page_filter.get(self.model): query = query.filter(url=param.get('url')) if query: self.single_page = True param['name'] = query[0].name #if self.request: # views = query[0].views # query.update(views=views+1) self.params = params if self.order: return query.order_by(self.order) else: return query def get_context_data(self, **kwargs): context = super(ExpoListView, self).get_context_data(**kwargs) context['filter'] = self.params context['single_page'] = self.single_page context['search_form'] = self.search_form if self.single_page: s = MetaSetting.objects.get(name='expo') obj = context['object_list'][0] params = s.generate_meta(obj) m = Meta(**params) context['meta'] = m return context from country.models import Country class EventDetail(ExpoMixin, DetailView): def get_object(self, queryset=None): obj = Country.objects.filter()[0] return obj from haystack.query import EmptySearchQuerySet class ExpoSearchView(ListView): paginate_by = settings.CLIENT_PAGINATION template_name = None search_form = None model = None def get_queryset(self): if self.request.GET: form = self.search_form(self.request.GET) if form.is_valid(): return form.search() else: return EmptySearchQuerySet() else: return EmptySearchQuerySet() def get_context_data(self, **kwargs): context = super(ExpoSearchView, self).get_context_data(**kwargs) if self.request.GET: form = self.search_form(self.request.GET) if form.is_valid(): form.data_with_parents = form.get_form_data() else: form = self.search_form() context['search_form'] = form queries = self.request.GET.copy() if queries.has_key('page'): del queries['page'] context['queries'] = queries return context from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.http import Http404 from django.views.generic import RedirectView from django.views.generic.detail import SingleObjectMixin class SimpleObjectChangeView(RedirectView, SingleObjectMixin): model = None url = None slug_field = 'url' slug_url_kwarg = 'url' attr = None attr_state = None query_string = True def get_object(self, queryset=None): """ Returns the object the view is displaying. By default this requires `self.queryset` and a `pk` or `slug` argument in the URLconf, but subclasses can override this to return any object. """ # Use a custom queryset if provided; this is required for subclasses # like DateDetailView if queryset is None: queryset = self.get_queryset() qs = self.model._default_manager.none() # Next, try looking up by url or primary key. slug = self.kwargs.get(self.slug_url_kwarg, None) if slug is not None: slug_field = self.get_slug_field() qs = queryset.filter(**{slug_field: slug}) if not qs: qs = queryset.filter(pk=slug) # If none of those are defined, it's an error. else: raise AttributeError("Generic detail view %s must be called with " "either an object pk or a slug." % self.__class__.__name__) try: # Get the single item from the filtered queryset obj = qs.get() except ObjectDoesNotExist: raise Http404(_("No %(verbose_name)s found matching the query") % {'verbose_name': qs.model._meta.verbose_name}) return obj def change_object(self, **kwargs): setattr(self.object, self.attr, self.attr_state) self.object.save(update_fields=[self.attr]) def get(self, request, *args, **kwargs): self.object = self.get_object() self.change_object() print(self.request.META.get('QUERY_STRING', '')) return super(SimpleObjectChangeView, self).get(request, *args, **kwargs) class BlockedFilterMixin(object): '''Filters default queryset with excluding blocked items ''' def get_queryset(self): qs = super(BlockedFilterMixin, self).get_queryset() return qs.filter(blocked=False)