diff --git a/accounts/forms.py b/accounts/forms.py index 678ce8ec..5e743285 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -120,33 +120,36 @@ class ChangePasswordForm(forms.Form): old_password = forms.CharField(label=_(u'Old password'), required=True, widget=forms.PasswordInput(render_value=False, attrs={'placeholder': _(u'Введите старый пароль')})) - new_password = forms.CharField(label=_(u'New password'), + new_password = forms.CharField(label=_(u'New password'), required=True, widget=forms.PasswordInput(render_value=False, attrs={'placeholder': _(u'Придумайте новый пароль')})) - new_password_confirm = forms.CharField(label=_(u'Confirm password'), + new_password_confirm = forms.CharField(label=_(u'Confirm password'), required=True, widget=forms.PasswordInput(render_value=False, attrs={'placeholder': _(u'Повторите новый пароль')})) def clean(self): - data = self.cleaned_data + data = super(ChangePasswordForm, self).clean() password1 = data.get('new_password') password2 = data.get('new_password_confirm') - + if not password1 or not password2: + return data + # self._errors['new_password'] = ErrorList([_(u'Different passwords!')]) + # return data if password1 and password2 and password1 != password2: # check if passwords exists and equal - self._errors['password'] = ErrorList([_(u'Different passwords!')]) - self._errors['password_confirm'] = ErrorList([_(u'Different passwords!')]) - del data['password'] - del data['password_confirm'] + self._errors['new_password'] = ErrorList([_(u'Пароли не совпадают!')]) + self._errors['new_password_confirm'] = ErrorList([_(u'Пароли не совпадают!')]) + del data['new_password_confirm'] + del data['new_password'] return data if not password1.isdigit() and any(char.isdigit() for char in password1) and len(password1)>5: # password must contain digits and letters and length > 5 return data else: - self._errors['new_password'] = ErrorList([_(u'Password must contain symbols and digits')]) - self._errors['new_password_confirm'] = ErrorList([_(u'Password must contain symbols and digits')]) - del data['password'] - del data['password_confirm'] + self._errors['new_password'] = ErrorList([_(u'Пароль должен содержать цифры и буквы')]) + self._errors['new_password_confirm'] = ErrorList([_(u'Пароль должен содержать цифры и буквы')]) + del data['new_password'] + del data['new_password_confirm'] return data class EmailAnnouncementForm(forms.Form): diff --git a/accounts/views.py b/accounts/views.py index 666157a8..b0a394ee 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -5,6 +5,7 @@ from django.template import RequestContext from django.core.context_processors import csrf from django.contrib.auth.decorators import login_required import random +from django.utils.translation import ugettext as _ #models and forms from models import User from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm @@ -12,6 +13,7 @@ from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnounce from functions.custom_views import objects_list from hashlib import md5 +import json @login_required @@ -162,73 +164,19 @@ def change_password(request): if form.is_valid(): user = request.user if(user.check_password(form.cleaned_data.get('old_password'))): - user.set_password(form.cleaned_data.get('new_password')) - user.save() + #user.set_password(form.cleaned_data.get('new_password')) + #user.save() success['success'] = True - success['message'] = _(u'Password has been changed') + success['message'] = _(u'Пароль именен') return HttpResponse(json.dumps(success), content_type='application/json') else: - errors = {'old_password': _(u'Invalid password')} + errors = {'errors': [_(u'Не правильный пароль')]} success.update(errors) return HttpResponse(json.dumps(success), content_type='application/json') else: - success.update(form.errors) + errors = [err[0] for err in form.errors.values()] + errors = {'errors': errors} + success.update(errors) return HttpResponse(json.dumps(success), content_type='application/json') else: return HttpResponse(json.dumps(success), content_type='application/json') -#-------------------------------------------------------------- -''' -from django.views.decorators.debug import sensitive_post_parameters -from django.views.decorators.cache import never_cache -from django.views.decorators.csrf import csrf_protect -from django.utils.http import base36_to_int, is_safe_url -from django.shortcuts import resolve_url -from django.conf import settings -from django.conf.global_settings import LOGIN_REDIRECT_URL -from django.contrib.auth.forms import AuthenticationForm - -@sensitive_post_parameters() -@csrf_protect -@never_cache -def login(request, template_name='registration/login.html', - redirect_field_name=REDIRECT_FIELD_NAME, - authentication_form=AuthenticationForm, - current_app=None, extra_context=None): - """ - Displays the login form and handles the login action. - """ - redirect_to = request.REQUEST.get(redirect_field_name, '') - - if request.method == "POST": - form = authentication_form(data=request.POST) - if form.is_valid(): - - # Ensure the user-originating redirection url is safe. - if not is_safe_url(url=redirect_to, host=request.get_host()): - redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) - - # Okay, security check complete. Log the user in. - auth_login(request, form.get_user()) - - if request.session.test_cookie_worked(): - request.session.delete_test_cookie() - - return HttpResponseRedirect(redirect_to) - else: - form = authentication_form(request) - - request.session.set_test_cookie() - - current_site = get_current_site(request) - - context = { - 'form': form, - redirect_field_name: redirect_to, - 'site': current_site, - 'site_name': current_site.name, - } - if extra_context is not None: - context.update(extra_context) - return TemplateResponse(request, template_name, context, - current_app=current_app) -''' \ No newline at end of file diff --git a/country/admin.py b/country/admin.py index 90b9bca5..1ca461b3 100644 --- a/country/admin.py +++ b/country/admin.py @@ -15,28 +15,21 @@ from file.forms import FileModelForm #custom views from functions.custom_views import objects_list, add_object_with_file, delete_object -from django.db.models.deletion import ProtectedError - - def country_all(request): """ Return list of all countries with pagination """ return objects_list(request, Country, 'country_all.html') - def country_add(request): """ Return form of country and file and post it on the server. """ return add_object_with_file(request, CountryForm, 'country_add.html', '/admin/country/all/') - def country_delete(request, url): return delete_object(request, Country, CountryDeleteForm, url, '/admin/country/all/') - -@login_required def country_change(request, url): """ Return form of county and file and fill it with existing Country object data. @@ -103,4 +96,4 @@ def country_change(request, url): #uses for creating hidden input which will be used for generating ajax url args['obj_id'] = country_id - return render_to_response('country_add.html', args) + return render_to_response('country_add.html', args) \ No newline at end of file diff --git a/country/admin2.py b/country/admin2.py deleted file mode 100644 index 495a1fa8..00000000 --- a/country/admin2.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -from django.contrib import admin -from hvad.admin import TranslatableAdmin -from models import Country -from bitfield import BitField -from bitfield.forms import BitFieldCheckboxSelectMultiple -from bitfield.admin import BitFieldListFilter - - -class CountryAdmin(TranslatableAdmin): - formfield_overrides = { - BitField: {'widget': BitFieldCheckboxSelectMultiple}, - } - - -admin.site.register(Country, CountryAdmin) diff --git a/country/forms.py b/country/forms.py index b79dd36a..0c0f5ffa 100644 --- a/country/forms.py +++ b/country/forms.py @@ -91,11 +91,11 @@ class CountryForm(forms.Form): self.fields['documents_%s' % code] = forms.CharField(label='Документы', required=False, widget=CKEditorWidget()) self.fields['consulate_%s' % code] = forms.CharField(label='Консульство', required=False, widget=CKEditorWidget()) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=required, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=required, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=required, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) # check if exists cities connected with country diff --git a/country/models.py b/country/models.py index 3ac465eb..08ca9757 100644 --- a/country/models.py +++ b/country/models.py @@ -74,10 +74,13 @@ from models import Country from django.dispatch import receiver from django.conf import settings from functions.form_check import translit_with_separator - - from functions.translate import get_translated_fields +from functions.signal_handlers import post_save_handler, post_save_translation_handler + +post_save.connect(post_save_handler, sender=Country) +post_save.connect(post_save_translation_handler, sender=CountryTranslation) +''' @receiver(post_save, sender=Country) def country_post_save_handler(sender, **kwargs): """ @@ -103,15 +106,16 @@ def country_post_save_handler(sender, **kwargs): for code in missing_languages: # translate obj.translate(code) - # go through all fields and set value + # set values equal to first translation for field in fields: setattr(obj, field, getattr(translation, field)) obj.save() if isinstance(obj, CountryTranslation): # object is Translation - print('success') if obj.language_code == 'ru': country = Country.objects.get(id=obj.master_id) + country.url = translit_with_separator(obj.name) - country.save() \ No newline at end of file + country.save() +''' \ No newline at end of file diff --git a/functions/__init__.py b/functions/__init__.py index e69de29b..3e7a4648 100644 --- a/functions/__init__.py +++ b/functions/__init__.py @@ -0,0 +1,53 @@ +#https://djangosnippets.org/snippets/2607/ +def required(wrapping_functions,patterns_rslt): + ''' + Used to require 1..n decorators in any view returned by a url tree + + Usage: + urlpatterns = required(func,patterns(...)) + urlpatterns = required((func,func,func),patterns(...)) + + Note: + Use functools.partial to pass keyword params to the required + decorators. If you need to pass args you will have to write a + wrapper function. + + Example: + from functools import partial + + urlpatterns = required( + partial(login_required,login_url='/accounts/login/'), + patterns(...) + ) + ''' + if not hasattr(wrapping_functions,'__iter__'): + wrapping_functions = (wrapping_functions,) + + return [ + _wrap_instance__resolve(wrapping_functions,instance) + for instance in patterns_rslt + ] + +def _wrap_instance__resolve(wrapping_functions,instance): + if not hasattr(instance,'resolve'): return instance + resolve = getattr(instance,'resolve') + + def _wrap_func_in_returned_resolver_match(*args,**kwargs): + rslt = resolve(*args,**kwargs) + + if not hasattr(rslt,'func'):return rslt + f = getattr(rslt,'func') + + for _f in reversed(wrapping_functions): + # @decorate the function from inner to outter + f = _f(f) + + setattr(rslt,'func',f) + + return rslt + + setattr(instance,'resolve',_wrap_func_in_returned_resolver_match) + + return instance + +#----------------------------- \ No newline at end of file diff --git a/functions/signal_additional_func.py b/functions/signal_additional_func.py index d450346c..5cff9251 100644 --- a/functions/signal_additional_func.py +++ b/functions/signal_additional_func.py @@ -6,58 +6,55 @@ from django.conf import settings from functions.translate import get_translated_fields def fill_missing_languages(obj): + """ + looking for missing languages + and fill translated fields with first available language + + uses in post_save signal + """ + + # what languages must be all_langs = [code for code, lang in settings.LANGUAGES] + # what languages are obj_langs = obj.get_available_languages() missing_languages = list(set(all_langs) - set(obj_langs)) - if missing_languages: - # get first Translation object (require) - translation = obj.translations.all()[0] - - fields = get_translated_fields(obj) - for code in missing_languages: - # translate - obj.translate(code) - # go through all fields and set value - for field in fields: - setattr(obj, field, getattr(translation, field)) - - obj.save() - -#from city.models import City -#city = City.objects.get(id=37) -#city.save() - -def fill_meta_information(obj): - s_list = settings_dict.get(obj.__class__.__name__) + # get first Translation object + translation = obj.translations.all()[0] + fields = get_translated_fields(obj) - if s_list: - for code, lang in settings.LANGUAGES: - fields_with_setting = {setting.get('field_name'): Setting.objects.get(key=setting['key']).get_value(code) \ - for setting in s_list if setting.get('type') =='transl'} - tr = obj._meta.translations_model.objects.get(language_code=code, master__id=getattr(obj, 'id')) - do_save = False - for field, value in fields_with_setting.iteritems(): - if getattr(tr, field) == '': - setattr(tr, field, value) - do_save = True - if do_save: - tr.save() - print 'save' + for code in missing_languages: + # translate + obj.translate(code) + # go through all fields and set value + for field in fields: + setattr(obj, field, getattr(translation, field)) + obj.save() - #return fields_with_setting - +def fill_meta_information(obj): """ + looking for available settings for this object + and fill empty field with settings rules + """ + # return list of settings for this object s_list = settings_dict.get(obj.__class__.__name__) - return s_list + for s in s_list: + # get Setting model object setting = Setting.objects.get(key=s.get('key')) + field = s.get('field_name') if setting.type != 'transl': - setattr(obj, s.get('field_name'), setting.get_value()) + # simple field + if getattr(obj, field)=="": + setattr(obj, field, setting.get_value()) + obj.save() else: + # translated field for code, lang in settings.LANGUAGES: + # get translation object tr = obj._meta.translations_model.objects.get(language_code=code, master__id=getattr(obj, 'id')) - setattr(tr, s.get('field_name'), setting.get_value(code)) - tr.save() - """ \ No newline at end of file + + if getattr(tr, field)=="": + setattr(tr, field, setting.get_value(code)) + tr.save() \ No newline at end of file diff --git a/functions/signal_handlers.py b/functions/signal_handlers.py new file mode 100644 index 00000000..316a5946 --- /dev/null +++ b/functions/signal_handlers.py @@ -0,0 +1,26 @@ +from form_check import translit_with_separator +from signal_additional_func import fill_missing_languages, fill_meta_information + + +def post_save_handler(sender, **kwargs): + """ + receiver function + take object + fill missing languages + fill settings if its exist for this object + + """ + obj = kwargs['instance'] + fill_missing_languages(obj) + fill_meta_information(obj) + + +def post_save_translation_handler(sender, **kwargs): + """ + receiver function + take object and change url + """ + obj = kwargs['instance'] + if obj.language_code == 'ru': + obj.master.url = translit_with_separator(obj.name) + obj.master.save() \ No newline at end of file diff --git a/place_conference/forms.py b/place_conference/forms.py index a859cc8f..98596f52 100644 --- a/place_conference/forms.py +++ b/place_conference/forms.py @@ -9,7 +9,6 @@ from django.forms.util import ErrorList from models import PlaceConference, Hall, CONFERENCE_TYPE from country.models import Country from city.models import City -from proj.models import Settings #functions from functions.translate import populate_all, fill_trans_fields_all from functions.files import check_tmp_files diff --git a/place_exposition/forms.py b/place_exposition/forms.py index 99240865..0d778750 100644 --- a/place_exposition/forms.py +++ b/place_exposition/forms.py @@ -9,7 +9,6 @@ from django.forms.util import ErrorList from models import PlaceExposition, EXPOSITION_TYPE, Hall from country.models import Country from city.models import City -from proj.models import Settings #functions from functions.translate import populate_all, fill_trans_fields_all from functions.files import check_tmp_files diff --git a/proj/admin.py b/proj/admin.py new file mode 100644 index 00000000..786c3900 --- /dev/null +++ b/proj/admin.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +from django.shortcuts import render_to_response +from django.http import HttpResponseRedirect, HttpResponse +from django.contrib.contenttypes.models import ContentType +from django.contrib.auth.decorators import login_required +from django.contrib.admin.views.decorators import staff_member_required +from file.models import TmpFile, FileModel +from file.forms import FileModelForm +from city.models import City +from theme.models import Tag +from django.db.models.loading import get_model + + +def admin_home(request): + return render_to_response('base.html') + +def ajax_city(request): + """ + returns html