You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

502 lines
17 KiB

# -*- 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)
class AjaxableResponseMixin(object):
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
'pk': self.object.pk,
}
return JsonResponse(data)
else:
return response