def update_language_tab_context(self, request, obj=None, context=None): """ Функция обновления контекста шаблона на основании языковых настроек. """ if not context: context = {} language = get_language_from_request(request, obj) context.update({ 'langgetvars': get_query_string(request.GET, remove=['language'], addq=False), 'language': language, 'traduction_language': settings.SCMS_LANGUAGES, 'show_language_tabs': len(settings.SCMS_LANGUAGES) > 1, }) return context
def parse_destination(self, request, obj=None): """ Анализирует GET['destination'] и формирует путь по которому необходимо перейти """ destination = request.GET.get('destination', '../') if destination == 'alias': edit_lang = get_language_from_request(request) if obj.state == page_state.MAIN: destination = "/" else: try: destination = self.slug_model.objects.get(page=obj, language=edit_lang).alias.replace('*', '') except self.slug_model.DoesNotExist: # на случай если destination == alias, а записи в слугс нет return "/" if not edit_lang == get_default_language() and not edit_lang == get_language(): # для того, чтобы при возврате на 'alias' страница отображалась не на языке по-умолчанию, а на редактируемом destination = '/%s%s' % (edit_lang, destination) return destination
def add_view(self, request, form_url='', extra_context=None): tab_language = get_language_from_request(request, None) parent_id = None try: parent_id = int(request.GET.get('parent')) request.scms['page'] = self.model.objects.get(id=parent_id) except (ValueError, TypeError, self.model.DoesNotExist): request.scms['page'] = self.model(id=None).full_load() request.scms['page_type'] = request.GET.get('type', '__undefined__') # произвольное редкое имя, чтобы сл. функция вернула ложь parent_content_type = scms.site.get_content_type(request.scms['page'].type) if not request.user.is_superuser and not request.scms['page_type'] in parent_content_type.children: raise Http404() request.scms['has_add_permission'] = True extra_context = self.update_language_tab_context(request, None, extra_context) extra_context['destination'] = request.GET.get('destination', None) extra_context['breadcrumbs'] = self.model(id=parent_id).full_load(tab_language).parents return super(PageAdmin, self).add_view(request, form_url, extra_context)
def get_plugin_formset(self, request, obj=None, instance=None, **kwargs): # import debug # defaults = { # 'auto_id': self.auto_id, # 'prefix': self.add_prefix(i), # 'error_class': self.error_class, # # Don't render the HTML 'required' attribute as it may cause # # incorrect validation for extra, optional, and deleted # # forms in the formset. # 'use_required_attribute': False, # } # defaults.update(kwargs) FormSet = self.get_formset(request, obj, **kwargs) language = self.lang_depended and get_language_from_request(request, None) or '' FormSet._queryset = self.model.objects.filter(language=language, page=instance, field_name=self.name).order_by('weight') # Фильтр на каком основании брать данные для полей плагина FormSet.form.page = instance # возможно, эти три строки неактуальны тк в пагеадмин есть request.change_page = obj obj? с целью, чтобы формы плагинов имели данные о странице FormSet.form.language = language FormSet.form.admin_field = self if request.POST: formset = FormSet(request.POST, request.FILES, instance=instance, prefix=self.name) # Можно было бы вынести и в общий блок (за пределы условия), но этот код вызывается только когда происходит save_formset. А это на данный момент только при POST-запросе for next_form in formset.extra_forms: for field in next_form.instance._meta.fields: if field.name == 'language': field.save_form_data(next_form.instance, language) if field.name == 'field_name': field.save_form_data(next_form.instance, self.name) else: formset = FormSet(instance=instance, prefix=self.name) # Добавим help_text, если он указан в плагине formset.help_text = self.help_text return formset
def scms_mongo_render(request, alias=''): # Формирование страницы db = get_mongo() if not db: return scms_render(request, alias) import pymongo request.scms = {} lang = get_language_from_request(request) if alias: query = {'language':lang, '$or': [{'alias': '*/%s' % alias}, {'alias': '/%s' % alias}]} slug = MongoManager(query) is_front = False # import debug # Чтобы главная страница не дублировалась с двумя адресами if slug.state == page_state.MAIN: return HttpResponseRedirect('/') else: # slug = Slugs.objects.filter(page__state=page_state.MAIN, language=lang)[0] # Сделать выдачу исключения , что нет главной страницы slug = MongoManager({'state':1, 'language':lang}) is_front = True # import debug if not slug.pk: raise Http404() elif slug.count() > 1: raise Http404('Exception: Slugs.MultipleObjectsReturned') if not slug.published and alias != 'search': raise Http404() # try: # cp = Page(id=slug.page_id).full_load(request=request, only_cached=False) # объект текущей страницы # except Page.DoesNotExist: # raise Http404() cp = slug is_inner = cp.parent_id and True or False pp = is_inner and MongoManager({'id':cp.parent_id}) or False request.scms['cp'] = cp lang_prefix = not lang == get_default_language() and ('/%s' % lang) or '' # Подготавливаем сервисные ссылки для быстрого доступа к админке scms_links = [] if request.user.id: # Чтобы лишние запросы к БД не создовались from scms.admin.pageadmin import PageAdmin pageadmin = PageAdmin(scms.models.pagemodel.Page, False) if pageadmin.has_change_permission(request, cp): getlang = not lang == get_default_language() and '&language=%s' % lang or '' scms_links.append({ 'name': _('Edit'), 'href': '/admin/scms/page/%s/?destination=alias%s' % (cp.pk, getlang) }) if pageadmin.has_delete_permission(request, cp): link = pp and pp.link or '/' scms_links.append({ 'name': _('Delete'), 'href': '/admin/scms/page/%s/delete/?destination=%s' % (cp.pk, link ) }) # parent_content_type = scms.site.get_content_type(cp.type) # for children_name in parent_content_type.children: # next_content_type = scms.site.get_content_type(children_name) # if not pageadmin.has_add_permission(request, parent_page=cp, type=children_name): # continue # scms_links.append({ # 'name': _('Create %s') % force_text(next_content_type.name), # 'href': '/admin/scms/page/add/?type=%s&parent=%s&destination=%s' % (next_content_type.id, cp.pk, get_destination(request) ) # }) # if request.user.is_staff: # scms_links.append({ # 'name': _('Go to CMS'), # 'href': '/admin/', # }) request.scms_page = cp # сохраняем в request текущую просматриваемую страницу, чтобы можно было ее использовать например в plugins.contact_form Чтобы знать с какой страницы отправлено сообщение context = { 'title': slug.title, 'link': cp.link, 'page_id': cp.id, 'parent_id': cp.parent_id, 'lang_prefix': lang_prefix, 'lang': lang, 'is_inner': is_inner, # т.е. если страница не в корне 'is_front': is_front, 'scms_links': scms_links, 'request': request, 'cp': cp, 'pp': pp, 'now': datetime.datetime.now().strftime("%Y-%m-%d %H:%M") , 'breadcrumbs': cp.get_parents() } # context.update(csrf(request)) # context.update(request) # Формируем обращаемся к страницам for source in ['%s-%s' % (cp.type, cp.id), cp.type, 'common']: try: mod = import_module('pages.' + source) except SyntaxError as err: raise SyntaxError(err) except ImportError: continue prepare_func = getattr(mod, 'prepare') if prepare_func: result = prepare_func(request, context, alias) if result: return result subtype = request.GET.get('subtype', '') templates = ['page-%s-%s-%s-%s.html' % (cp.type, cp.id, lang, subtype), 'page-%s-%s-%s.html' % (cp.type, cp.id, lang), 'page-%s-%s-%s.html' % (cp.type, cp.id, subtype), 'page-%s-%s.html' % (cp.type, cp.id), 'page-%s-%s-%s.html' % (cp.type, lang, subtype), 'page-%s-%s.html' % (cp.type, lang), 'page-%s-%s.html' % (cp.type, subtype), 'page-%s.html' % cp.type, 'page-common-%s.html' % lang, 'page-common.html',] response = render(request, templates, context) #smart_cache.go(html_cache_fpathname, 0, depended_types=self.depended_types, adition_dependies=self.adition_dependies, delete_callback=None) # Сохранение сформированной страницы в кеш #try: # dirname = os.path.dirname(html_cache_fpathname) # if not os.path.exists(dirname): # os.makedirs(dirname) # html_cache_fhandle = open(html_cache_fpathname, 'w+') # html_cache_fobj = File(html_cache_fhandle) # html_cache_fobj.write(response.content) # html_cache_fobj.close() #except OSError: # pass return response
def scms_render(request, alias=''): # Подготовка имени файла для механизма кеширования целых страниц #html_cache_fname = alias and alias or 'index' #if request.environ['QUERY_STRING']: # html_cache_fname = html_cache_fname + '&&&' + request.environ['QUERY_STRING'] #html_cache_fpathname = settings.SITE_ROOT + settings.TMP_DIR + 'html_cache/' + html_cache_fname + '.html' # Попытка загрузки кеша из файла #try: # html_cache_fhandle = open(html_cache_fpathname, 'r') # html_cache_fobj = File(html_cache_fhandle) # content = html_cache_fobj.read() # html_cache_fobj.close() # return HttpResponse(content) #except IOError: # pass # Формирование страницы request.scms = {} lang = get_language_from_request(request) try: if alias: #slug = Slugs.objects.get(alias__regex=r'^[\*]?/%s$' % alias, language=lang) slug = Slugs.objects.get(Q(alias='*/%s' % alias) | Q(alias='/%s' % alias), language=lang) #, page__published=True) is_front = False # Чтобы главная страница не дублировалась с двумя адресами if slug.page.state == page_state.MAIN: return HttpResponseRedirect('/') else: slug = Slugs.objects.filter(page__state=page_state.MAIN, language=lang)[0] # Сделать выдачу исключения , что нет главной страницы is_front = True except Slugs.DoesNotExist: raise Http404() except Slugs.MultipleObjectsReturned: raise Http404('Exception: Slugs.MultipleObjectsReturned') if not slug.page.published and alias != 'search': raise Http404() try: cp = Page(id=slug.page_id).full_load(request=request, only_cached=False) # объект текущей страницы except Page.DoesNotExist: raise Http404() is_inner = cp.parent_id and True or False pp = is_inner and Page(id=cp.parent_id).full_load(request=request) or False request.scms['cp'] = cp lang_prefix = not lang == get_default_language() and ('/%s' % lang) or '' # Подготавливаем сервисные ссылки для быстрого доступа к админке scms_links = [] if request.user.id: # Чтобы лишние запросы к БД не создовались from scms.admin.pageadmin import PageAdmin pageadmin = PageAdmin(scms.models.pagemodel.Page, False) if pageadmin.has_change_permission(request, cp): getlang = not lang == get_default_language() and '&language=%s' % lang or '' scms_links.append({ 'name': _('Edit'), 'href': '/admin/scms/page/%s/?destination=alias%s' % (cp.pk, getlang) }) if pageadmin.has_delete_permission(request, cp): link = pp and pp.link or '/' scms_links.append({ 'name': _('Delete'), 'href': '/admin/scms/page/%s/delete/?destination=%s' % (cp.pk, link ) }) parent_content_type = scms.site.get_content_type(cp.type) for children_name in parent_content_type.children: next_content_type = scms.site.get_content_type(children_name) if not pageadmin.has_add_permission(request, parent_page=cp, type=children_name): continue scms_links.append({ 'name': _('Create %s') % force_text(next_content_type.name), 'href': '/admin/scms/page/add/?type=%s&parent=%s&destination=%s' % (next_content_type.id, cp.pk, get_destination(request) ) }) if request.user.is_staff: scms_links.append({ 'name': _('Go to CMS'), 'href': '/admin/', }) request.scms_page = cp # сохраняем в request текущую просматриваемую страницу, чтобы можно было ее использовать например в plugins.contact_form Чтобы знать с какой страницы отправлено сообщение context = { 'title': slug.title, 'link': cp.link, 'page_id': slug.page_id, 'parent_id': cp.parent_id, 'lang_prefix': lang_prefix, 'lang': lang, 'is_inner': is_inner, # т.е. если страница не в корне 'is_front': is_front, 'scms_links': scms_links, 'request': request, 'cp': cp, 'pp': pp, 'now': datetime.datetime.now().strftime("%Y-%m-%d %H:%M") , 'breadcrumbs': cp.parents, } # import debug # context.update(csrf(request)) # context.update(dict(request)) # Формируем обращаемся к страницам for source in ['%s-%s'%(cp.type, cp.id), cp.type, 'common']: try: mod = import_module('pages.' + source) except SyntaxError as err: raise SyntaxError(err) except ImportError: continue prepare_func = getattr(mod, 'prepare') if prepare_func: result = prepare_func(request, context, alias) if result: return result subtype = request.GET.get('subtype', '') response = render(request, ['page-%s-%s-%s-%s.html' % (cp.type, cp.id, lang, subtype), 'page-%s-%s-%s.html' % (cp.type, cp.id, lang), 'page-%s-%s-%s.html' % (cp.type, cp.id, subtype), 'page-%s-%s.html' % (cp.type, cp.id), 'page-%s-%s-%s.html' % (cp.type, lang, subtype), 'page-%s-%s.html' % (cp.type, lang), 'page-%s-%s.html' % (cp.type, subtype), 'page-%s.html' % cp.type, 'page-common-%s.html' % lang, 'page-common.html',], context) #smart_cache.go(html_cache_fpathname, 0, depended_types=self.depended_types, adition_dependies=self.adition_dependies, delete_callback=None) # Сохранение сформированной страницы в кеш #try: # dirname = os.path.dirname(html_cache_fpathname) # if not os.path.exists(dirname): # os.makedirs(dirname) # html_cache_fhandle = open(html_cache_fpathname, 'w+') # html_cache_fobj = File(html_cache_fhandle) # html_cache_fobj.write(response.content) # html_cache_fobj.close() #except OSError: # pass return response
def changelist_view(self, request, extra_context=None): tab_language = get_language_from_request(request, None) self._request = request extra_context = extra_context or {} parent_id = None try: parent_id = int(request.GET.get('parent__id__exact')) request.scms['page'] = self.model.objects.get(id=parent_id) except (ValueError, TypeError, self.model.DoesNotExist): request.scms['page'] = self.model(id=None).full_load() request.scms['page_type'] = request.scms['page'].type parent = self.model(id=parent_id).full_load(tab_language) try: extra_context.update({ 'parent_id': parent_id, 'destination': get_destination(request), 'breadcrumbs': self.model(id=parent_id).full_load(tab_language).parents, 'opts': self.model._meta, # для темплэйта breadcrumbs.html }) except: pass parent = self.model(id=parent_id).full_load() parent_content_type = scms.site.get_content_type(request.scms['page_type']) # Подготавливаем ячейки просмотра/редактирования от плагинов admin_list_ext = [] # Ниже вставляется в self.list_display for plugin_field_info in parent_content_type.get_changelist_fields(True): if isinstance(plugin_field_info, dict): list_name = plugin_field_info['list_name'] def ext_field_view(obj): val = getattr(obj, list_name, '') return val and val or '' ext_field_view.allow_tags = True ext_field_view.short_description = plugin_field_info['column_name'] setattr(self, plugin_field_info['list_name'], ext_field_view) admin_list_ext += [plugin_field_info['list_name']] # в self.list_display должна быть строка, поэтому сохраняем только имя поля(функции-обработчика) else: admin_list_ext += [plugin_field_info] if not '_popup' in request.GET: # 'action_checkbox', убрал из следующей строчки первым пунктом, т.к. у нас не испльзуются действия, см. также. объявление класса self.list_display = ['adminlist_icon', 'adminlist_title', 'adminlist_state'] + admin_list_ext + ['adminlist_actions'] # В функцию вынесено с целью упрощенного переопределения self.list_editable = [field for field in ['weight', 'date', 'published', 'hidden', 'expanded'] if field in self.list_display] else: # 'action_checkbox', убрал из следующей строчки первым пунктом, т.к. у нас не испльзуются действия, см. также. объявление класса self.list_display = ['adminlist_empty', 'adminlist_icon', 'adminlist_title', 'type', 'adminlist_actions',] # В функцию вынесено с целью упрощенного переопределения self.list_editable = [] # Формирование списка ссылок для добавления новых страниц add_list = [] for children_name in parent_content_type.children: next_content_type = scms.site.get_content_type(children_name) if not self.has_add_permission(request, parent_page=request.scms['page'], type=children_name): continue add_list.append(next_content_type) extra_context.update({'add_list': add_list}) return super(PageAdmin, self).changelist_view(request, extra_context)
def change_view(self, request, object_id, form_url='', extra_context=None): tab_language = get_language_from_request(request, None) to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) "The 'change' admin view for this model." model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if not self.has_change_permission(request, obj): messages.warning(request, _("You have no permissions to change %(name)s") % {"name": obj}) if request.GET.get('destination'): dest_url = self.parse_destination(request, obj) else: dest_url = reverse('admin:%s_%s_changelist' % (opts.app_label, opts.model_name), current_app=self.admin_site.name) return HttpResponseRedirect(dest_url) if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) request.scms['page_type'] = obj.type request.scms['page'] = obj #if request.method == 'POST' and "_saveasnew" in request.POST: #raise PermissionDenied # Не реализовано #if not request.user.is_superuser and 'create' in scms.site.get_content_type(obj.type).permissions: # return self.add_view(request, form_url='../add/%s' % obj.type, current_app=self.admin_site.name) #else: # raise PermissionDenied ModelForm = self.get_form(request, obj) formsets = [] inline_instances = scms.site.get_content_type(obj.type).get_fields(obj) if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=obj, language=tab_language) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) # Возвращается просто объект страницы, но запись в БД еще не происходила # тк еще надо проверь корректность inline ов else: form_validated = False new_object = obj for inline in inline_instances: inline.init(self.model, self.admin_site) formset = inline.get_plugin_formset(request, obj, instance=new_object) formsets.append(formset) if all_valid(formsets) and form_validated: if "_saveasnew" in request.POST: new_object = self.copy_page(new_object) self.save_related(request, form, formsets, True) self.save_model(request, new_object, form, True) change_message = self.construct_change_message(request, form, formsets) self.log_change(request, new_object, change_message) response = self.response_change(request, new_object) # стандартный обработчик if tab_language and response.status_code == 302 and response._headers['location'][1] == request.path: location = response._headers['location'] response._headers['location'] = (location[0], "%s?language=%s" % (location[1], tab_language)) return response else: form = ModelForm(instance=obj, language=tab_language) for inline in inline_instances: inline.init(self.model, self.admin_site) formset = inline.get_plugin_formset(request, None, instance=obj) formsets.append(formset) fieldsets = self.get_fieldsets(request, obj) adminForm = helpers.AdminForm( form, list(self.get_fieldsets(request, obj)), self.get_prepopulated_fields(request, obj), self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) readonly = list(inline.get_readonly_fields(request, obj)) prepopulated = dict(inline.get_prepopulated_fields(request, obj)) inline_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_formset) media = media + inline_formset.media fullobj = form.instance.full_load(language=tab_language) # context = { # 'title': _('Change %s') % force_text(opts.verbose_name), #TODO: указывать тип создаваемой страницы # 'adminform': adminForm, # 'object_id': object_id, # 'original': obj, # 'is_popup': "_popup" in request.GET or "_popup" in request.POST, # 'media': media, # 'inline_admin_formsets': inline_admin_formsets, # 'errors': helpers.AdminErrorList(form, formsets), # 'app_label': opts.app_label, # #TODO!!!'root_path': self.admin_site.root_path, # 'view_path': fullobj and fullobj.link or None , # 'destination': self.parse_destination(request, obj), # 'has_permission': True, # 'breadcrumbs': self.model(id=obj.parent_id).full_load().parents + [obj.full_load()], # } context = dict( self.admin_site.each_context(request), title=_('Change %s') % opts.verbose_name, adminform=adminForm, object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, media=media, inline_admin_formsets=inline_admin_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), view_path=fullobj and fullobj.link or None , breadcrumbs=list(obj.get_parents()) + [obj.full_load(tab_language)], has_permission=True, destination=self.parse_destination(request, obj), ) context = self.update_language_tab_context(request, None, context) extra_context = self.update_language_tab_context(request, None, extra_context) extra_context['destination'] = request.GET.get('destination', None) form_url = form_url # extra_context['breadcrumbs'] = self.model(id=parent_id).full_load(tab_language).parents context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)