From 77a5bddb6db56c15100521bf3bcd00fd73691cbc Mon Sep 17 00:00:00 2001 From: Nazar Kotjuk Date: Wed, 13 Nov 2013 12:54:56 +0200 Subject: [PATCH] commit --- accounts/admin.py | 2 +- accounts/forms.py | 9 +- accounts/models.py | 21 +- accounts/urls.py | 3 +- accounts/views.py | 58 ++--- article/forms.py | 8 +- article/models.py | 2 +- article/views.py | 6 +- company/models.py | 1 + news/forms.py | 31 +-- news/models.py | 2 +- news/views.py | 4 +- organiser/forms.py | 8 + organiser/views.py | 3 + proj/settings.py | 7 + templates/admin/accounts/registration.html | 14 ++ templates/admin/article/article_all.html | 2 +- templates/admin/country/country_add.html | 2 +- templates/admin/news/news_add.html | 10 +- templates/admin/organiser/organiser_add.html | 7 + templates/admin/theme/tag_all.html | 2 +- .../admin/translator/translator_add.html | 228 ++++++++++++++++++ .../admin/translator/translator_all.html | 59 +++++ templates/base.html | 7 +- theme/forms.py | 11 +- translator/forms.py | 35 ++- translator/models.py | 5 +- translator/views.py | 73 +++++- 28 files changed, 504 insertions(+), 116 deletions(-) create mode 100644 templates/admin/accounts/registration.html create mode 100644 templates/admin/translator/translator_add.html create mode 100644 templates/admin/translator/translator_all.html diff --git a/accounts/admin.py b/accounts/admin.py index 40b4f044..3dd04327 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -21,7 +21,7 @@ class UserAdmin(UserAdmin): (None, {'fields': ('url', 'country', 'city', 'position', 'about', 'phone', 'avatar', 'web_page', 'social', 'title', 'descriptions', 'keywords', - 'is_admin', 'is_active', 'is_translator', 'is_organiser')}), + 'is_admin', 'is_active')}), ) add_fieldsets = ( diff --git a/accounts/forms.py b/accounts/forms.py index 5c47a7dc..4008c976 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django import forms from django.contrib.auth.forms import ReadOnlyPasswordHashField -from models import User, TranslatorProfile +from models import User from country.models import Country from city.models import City from company.models import Company @@ -108,9 +108,4 @@ class UserForm(forms.ModelForm): socket.getaddrinfo(web_page, 80) return web_page except: - return forms.ValidationError('Введите правильный адрес страници') - -class TranslatorForm(forms.ModelForm): - class Meta: - model = TranslatorProfile - exclude = ('user') \ No newline at end of file + return forms.ValidationError('Введите правильный адрес страници') \ No newline at end of file diff --git a/accounts/models.py b/accounts/models.py index b85e2f5e..ffbae91b 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -89,9 +89,11 @@ class User(AbstractBaseUser, PermissionsMixin): date_modified = models.DateTimeField(auto_now=True) #relations organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True, + unique=True, on_delete=models.PROTECT) translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True, - on_delete=models.PROTECT) + unique=True, + on_delete=models.PROTECT, related_name='user') country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, on_delete=models.PROTECT, related_name='users') city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, @@ -128,8 +130,6 @@ class User(AbstractBaseUser, PermissionsMixin): """ self.url = translit_with_separator(u'%s'%st) - - def __unicode__(self): return self.email @@ -150,21 +150,6 @@ class User(AbstractBaseUser, PermissionsMixin): return True -class TranslatorProfile(models.Model): - """ - Extra information about translators - """ - education = models.CharField(verbose_name='Образование', max_length=255, blank=True) - specialization = models.CharField(verbose_name='Специализация', max_length=255, blank=True) - languages = models.CharField(verbose_name='Языки', max_length=255, blank=True) - native_language= models.CharField(verbose_name='Родной язык', max_length=255, blank=True) - car = models.BooleanField(verbose_name='Личный автомобиль', default=0) - prices = models.TextField(verbose_name='Тарифы', blank=True) - discounts = models.TextField(verbose_name='Скидки', blank=True) - - def __unicode__(self): - return self.user.email - #need import after User Model, because User imported in "organiser.models" from organiser.models import Organiser diff --git a/accounts/urls.py b/accounts/urls.py index 49c5e718..d777473b 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -5,13 +5,12 @@ from django.contrib.auth.views import login, logout urlpatterns = patterns('', url(r'^login/', login, {'template_name': 'admin/login.html' }), url(r'^logout', logout, {'next_page': '/accounts/login/'}), + url(r'^registration/$', 'accounts.views.registration'), url(r'^create_admin/$', 'accounts.views.create_admin'), url(r'^create_md5user/$', 'accounts.views.create_md5'), url(r'^change/(.*)/$', 'accounts.views.user_change'), # url(r'^change/(?P\d+).*/$', 'accounts.views.user_change'), url(r'^all/$', 'accounts.views.user_all'), - url(r'^translators/$', 'accounts.views.translators'), - url(r'^translators/(?P\d+)/$', 'accounts.views.translator_change'), url(r'^reset_password_email/$', 'accounts.views.reset_password_email'), ) \ No newline at end of file diff --git a/accounts/views.py b/accounts/views.py index 0af8e5b7..329a5429 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -5,9 +5,9 @@ from django.core.context_processors import csrf from django.contrib.auth.decorators import login_required #models and forms from models import User -from forms import UserForm, UserCreationForm, TranslatorForm +from forms import UserForm, UserCreationForm #custom views -from functions.custom_views import objects_list, filtered_list +from functions.custom_views import objects_list from hashlib import md5 @@ -18,44 +18,6 @@ def user_all(request): """ return objects_list(request, User, 'user_all.html') -def translators(request): - """ - Return list of user filtered by "is_translator" field (list of translators) - """ - user_list = User.objects.filter(is_translator='True') - return filtered_list(request, user_list, 'translators.html') - - -def translator_change(request, user_id): - """ - Return form of translator and post it on the server. - If form is posted redirect on the page of all translators. - """ - try: - user = User.objects.get(id=user_id) - #get translator information by reverse relation - #related_name="translator" in TranslatorProfile model - translator = user.translator.get(user=user) - except: - return HttpResponseRedirect('/accounts/translators/') - - if request.POST: - form = TranslatorForm(request.POST, instance=translator) - if form.is_valid(): - form.save() - return HttpResponseRedirect('/accounts/translators') - else: - form = TranslatorForm(instance=translator) - - args = {} - args.update(csrf(request)) - - args['form'] = form - - return render_to_response('translator_change.html', args) - - - def user_change(request, url): """ Return form of user and post it on the server. @@ -125,6 +87,22 @@ def create_md5(request): return render_to_response('create_admin.html', args) +def registration(request): + if request.POST: + form = UserCreationForm(request.POST) + if form.is_valid(): + form.save() + return HttpResponseRedirect('/accounts/registration') + else: + form = UserCreationForm() + + args = {} + args.update(csrf(request)) + + args['form'] = form + + return render_to_response('registration.html', args) + def reset_password_email(request): """ diff --git a/article/forms.py b/article/forms.py index 441501d3..443b5afa 100644 --- a/article/forms.py +++ b/article/forms.py @@ -10,7 +10,7 @@ from functions.files import check_tmp_files from functions.form_check import translit_with_separator #models from models import Article -from organiser.models import Organiser +from accounts.models import User from theme.models import Theme, Tag @@ -22,7 +22,9 @@ class ArticleForm(forms.Form): save function saves data in Article object. If it doesnt exist create new object """ - author = forms.ModelChoiceField(label='Автор',queryset=Organiser.objects.all()) + #users that have organiser profile + author = forms.ModelChoiceField(label='Автор',queryset=User.objects.exclude(organiser__isnull=True)) + key = forms.CharField(required=False, widget=forms.HiddenInput()) theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax @@ -72,7 +74,7 @@ class ArticleForm(forms.Form): if data.get('author'): - article.organiser = Organiser.objects.get(id=data['author'].id)#.id cause select uses queryset + article.user = User.objects.get(id=data['author'].id)#.id cause select uses queryset #create slug field from russian language article.url = translit_with_separator(data['main_title_ru']).lower() diff --git a/article/models.py b/article/models.py index d8da9da1..32b55780 100644 --- a/article/models.py +++ b/article/models.py @@ -13,7 +13,7 @@ class Article(TranslatableModel): url = models.SlugField(unique=True) theme = models.ManyToManyField('theme.Theme') tag = models.ManyToManyField('theme.Tag', related_name='tags',blank=True, null=True) - organiser = models.ForeignKey('organiser.Organiser', verbose_name='Автор', + user = models.ForeignKey('accounts.User', verbose_name='Автор', on_delete=models.PROTECT, related_name='articles') #translated fields diff --git a/article/views.py b/article/views.py index f879951d..43f3a24e 100644 --- a/article/views.py +++ b/article/views.py @@ -10,7 +10,7 @@ from forms import ArticleForm, ArticleDeleteForm, Article from theme.models import Tag from file.models import FileModel, TmpFile from file.forms import FileModelForm -from organiser.models import Organiser + #custom views from functions.custom_views import objects_list, add_object_with_file, delete_object @@ -28,7 +28,7 @@ def article_add(request): If form is posted redirect on the page of all articles. """ #get organiser from current user - init_data = {'author':request.user.organiser.all()[0]} + init_data = {'author':request.user.organiser} #choices field which will be filled by ajax choices = {'tag': Tag} return add_object_with_file(request, ArticleForm, 'article_add.html', '/article/all', @@ -65,7 +65,7 @@ def article_change(request, url): else: data = {} #fill form with data from database - data['author'] = article.organiser + data['author'] = article.user data['theme'] = [item.id for item in article.theme.all()] data['tag'] = [item.id for item in article.tag.all()] #hidden field diff --git a/company/models.py b/company/models.py index cb8b2bb0..4370b7dc 100644 --- a/company/models.py +++ b/company/models.py @@ -25,6 +25,7 @@ class Company(TranslatableModel): url = models.SlugField() #relations + creator = models.ForeignKey('accounts.User', verbose_name='Создатель', related_name='created_company') theme = models.ManyToManyField('theme.Theme', verbose_name='Отрасль', blank=True, null=True, related_name='companies') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True, related_name='companies') diff --git a/news/forms.py b/news/forms.py index b2437778..8bf0091b 100644 --- a/news/forms.py +++ b/news/forms.py @@ -4,9 +4,10 @@ from django.conf import settings from django.contrib.contenttypes.models import ContentType from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError +#models and forms from models import News, TYPES from theme.models import Theme -from organiser.models import Organiser +from accounts.models import User from django.db.models.loading import get_model #functions from functions.translate import populate_all, fill_trans_fields_all @@ -31,7 +32,8 @@ class NewsForm(forms.Form): theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax tag = forms.MultipleChoiceField(label='Теги', required=False) - organiser = forms.ModelChoiceField(label='Организатор', queryset=Organiser.objects.all(), empty_label='') + user = forms.ModelChoiceField(label='Организатор', queryset=User.objects.exclude(organiser__isnull=True), + empty_label=None) # event = forms.ChoiceField(label='Тип события', choices=[(None, ''), ('conference.Conference', 'Конференция'), ('exposition.Exposition', 'Выставка')], required=False) @@ -81,17 +83,18 @@ class NewsForm(forms.Form): news.tag.clear() #save relation if its filled - obj = get_model(data['event'].split('.')[0],data['event'].split('.')[1]).objects.get(id=data['event_id']) - news.content_type = ContentType.objects.get_for_model(obj)# - news.object_id = data['event_id'] + if not data['event_id']: + obj = get_model(data['event'].split('.')[0],data['event'].split('.')[1]).objects.get(id=data['event_id']) + news.content_type = ContentType.objects.get_for_model(obj)# + news.object_id = data['event_id'] #simple fields news.url = translit_with_separator(data['main_title_ru']) news.date = data['date'] news.type = data['type'] news.paid = data['paid'] - if data.get('organiser'): - news.organiser = data['organiser'] + if data.get('user'): + news.user = data['user'] # uses because in the next loop data will be overwritten news.save() @@ -130,16 +133,4 @@ class NewsForm(forms.Form): except: return main_title_ru - raise ValidationError('Новость с таким названием уже существует') - - def clean_event_id(self): - """ - check event_id which must be filled only if event field filled - """ - cleaned_data = super(NewsForm, self).clean() - event = cleaned_data.get('event') - event_id = cleaned_data.get('event_id') - if not event_id and event: - raise ValidationError('Вы должны выбрать тип события') - else: - return event_id \ No newline at end of file + raise ValidationError('Новость с таким названием уже существует') \ No newline at end of file diff --git a/news/models.py b/news/models.py index 68df57bd..e45c1a82 100644 --- a/news/models.py +++ b/news/models.py @@ -18,7 +18,7 @@ class News(TranslatableModel): type = EnumField(values=TYPES) theme = models.ManyToManyField('theme.Theme', verbose_name='Тема') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True) - organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True, + user = models.ForeignKey('accounts.User', verbose_name='Организатор', blank=True, null=True, on_delete=models.PROTECT) paid = models.BooleanField(default=0) diff --git a/news/views.py b/news/views.py index de2a6246..371af012 100644 --- a/news/views.py +++ b/news/views.py @@ -100,8 +100,8 @@ def news_change(request, url): #fill form with data from database data = {'date':news.date, 'type':news.type, 'paid': news.paid} - if news.organiser: - data['organiser'] = news.organiser.id + if news.user: + data['user'] = news.user.id # if news.content_type: data['event'] = 'conference.Conference' if news.content_type.model=='conference'\ diff --git a/organiser/forms.py b/organiser/forms.py index a97f5692..f1dbf360 100644 --- a/organiser/forms.py +++ b/organiser/forms.py @@ -8,6 +8,7 @@ from models import Organiser from country.models import Country from city.models import City from theme.models import Theme +from accounts.models import User from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference #functions @@ -27,6 +28,7 @@ class OrganiserForm(forms.Form): """ url = forms.CharField(label='url', required=False) + user = forms.ModelChoiceField(label='Пользователь', queryset=User.objects.all(), empty_label=None) country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) place_exposition = forms.ModelMultipleChoiceField(label='Места проведения выставок', queryset=PlaceExposition.objects.all(), required=False) @@ -154,6 +156,12 @@ class OrganiserForm(forms.Form): #save files check_tmp_files(organiser, data['key']) + #bound organiser to user + user = User.objects.safe_get(id=data['user'].id) + if user: + user.organiser = organiser + user.save() + def clean_url(self): cleaned_data = super(OrganiserForm, self).clean() url = cleaned_data.get('url').strip() diff --git a/organiser/views.py b/organiser/views.py index d7c9ae12..12e6ee5a 100644 --- a/organiser/views.py +++ b/organiser/views.py @@ -7,6 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.auth.decorators import login_required #models and forms from models import Organiser +from accounts.models import User from city.models import City from theme.models import Tag from forms import OrganiserForm @@ -70,6 +71,8 @@ def organiser_change(request, url): 'fax':organiser.fax, 'web_page':organiser.web_page, 'url':organiser.url, 'email':organiser.email, 'social':organiser.social, 'foundation': organiser.foundation} + data['user'] = User.objects.safe_get(organiser=organiser) + if organiser.country: data['country'] = organiser.country.id diff --git a/proj/settings.py b/proj/settings.py index 5e4ebb95..104d2d88 100644 --- a/proj/settings.py +++ b/proj/settings.py @@ -22,6 +22,12 @@ DATABASES = { } } +EMAIL_USE_TLS = True +EMAIL_HOST = 'smtp.gmail.com' +EMAIL_HOST_USER = 'kotzillla@gmail.com' +EMAIL_HOST_PASSWORD = 'fitter2006' +EMAIL_PORT = 587 + # Hosts/domain names that are valid for this site; required if DEBUG is False # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts ALLOWED_HOSTS = [] @@ -157,6 +163,7 @@ TEMPLATE_DIRS = ( '/home/kotzilla/Documents/qwer/proj/templates/admin/seminar', '/home/kotzilla/Documents/qwer/proj/templates/admin/service', '/home/kotzilla/Documents/qwer/proj/templates/admin/theme', + '/home/kotzilla/Documents/qwer/proj/templates/admin/translator', '/home/kotzilla/Documents/qwer/proj/templates/admin/webinar', ) diff --git a/templates/admin/accounts/registration.html b/templates/admin/accounts/registration.html new file mode 100644 index 00000000..7546f4bd --- /dev/null +++ b/templates/admin/accounts/registration.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} + + +{% block body %} + +
{% csrf_token %} + + {{ form }} + + + + +
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/article/article_all.html b/templates/admin/article/article_all.html index 816ade9b..726c37d3 100644 --- a/templates/admin/article/article_all.html +++ b/templates/admin/article/article_all.html @@ -24,7 +24,7 @@ Displays lists of all articles in the table {{ item.id }} {{ item.main_title }} - {% ifnotequal item.author None %}{{ item.author }} {% endifnotequal %} + {% ifnotequal item.user None %}{{ item.user }} {% endifnotequal %} Изменить diff --git a/templates/admin/country/country_add.html b/templates/admin/country/country_add.html index dfe386b6..372a69a4 100644 --- a/templates/admin/country/country_add.html +++ b/templates/admin/country/country_add.html @@ -21,7 +21,7 @@ {# Uses multilang.html template for translated fields #}
{% csrf_token %}
- {% if country_id %} Изменить {% else %} Добавить {% endif %}страну + {% if obj_id %} Изменить {% else %} Добавить {% endif %}страну
diff --git a/templates/admin/news/news_add.html b/templates/admin/news/news_add.html index df3f2ef4..c582989d 100644 --- a/templates/admin/news/news_add.html +++ b/templates/admin/news/news_add.html @@ -86,11 +86,11 @@ {{ form.tag.errors }}
- {# organiser #} -
- -
{{ form.organiser }} - {{ form.organiser.errors }} + {# user #} +
+ +
{{ form.user }} + {{ form.user.errors }}
{# description #} diff --git a/templates/admin/organiser/organiser_add.html b/templates/admin/organiser/organiser_add.html index 851f3eeb..d86eb72b 100644 --- a/templates/admin/organiser/organiser_add.html +++ b/templates/admin/organiser/organiser_add.html @@ -40,6 +40,13 @@ {# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# user #} +
+ +
{{ form.user }} + {{ form.user.errors }} +
+
{# name #} {% with field='name' form=form languages=languages %} {% include 'admin/forms/multilang.html' %} diff --git a/templates/admin/theme/tag_all.html b/templates/admin/theme/tag_all.html index cddcb9c6..0d1dcb0f 100644 --- a/templates/admin/theme/tag_all.html +++ b/templates/admin/theme/tag_all.html @@ -27,7 +27,7 @@ {{ item.main_title }} -
+ Изменить diff --git a/templates/admin/translator/translator_add.html b/templates/admin/translator/translator_add.html new file mode 100644 index 00000000..31a46913 --- /dev/null +++ b/templates/admin/translator/translator_add.html @@ -0,0 +1,228 @@ +{% extends 'base.html' %} +{% load static %} +{# Displays translator form and file form in modal window #} + + +{% block scripts %} + + + {# selects #} + + + + {# ajax #} + + + {# datetimepicker #} + + + + + +{% endblock %} + +{% block body %} + +{# Uses multilang.html template for translated fields #} + {% csrf_token %} +
+ {% if obj_id %} Изменить {% else %} Добавить {% endif %}страну + +
+
+

Основная информация

+
+
+ {# Hidden input uses for comparing with TmpFile objects #} + {{ form.key }} + + {# user #} +
+ +
{{ form.user }} + {{ form.user.errors }} +
+
+ {# birth #} +
+ +
{{ form.birth }} + {{ form.birth.errors }} +
+
+ {# gender #} +
+ +
{{ form.gender }} + {{ form.gender.errors }} +
+
+ + {# education #} + {% with field='education' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# specialization #} + {% with field='specialization' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# languages #} + {% with field='languages' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# native_language #} + {% with field='native_language' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# prices #} + {% with field='prices' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# discounts #} + {% with field='discounts' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# car #} +
+ +
{{ form.car }} + {{ form.car.errors }} +
+
+ +
+
+ + +
+
+

Файлы

+
+
+ {# button that shows modal window with file form #} + Добавить файл + {# this div shows list of files and refreshes when new file added #} +
+ + + + + + + + + + + + + {% for file in files %} + + + + + + + + + + {% endfor %} + +
idФайлИмяНазначение
{{ file.id }}{{ file.file_name }}{{ file.purpose }} + +
+
+ +
+
+ + +
+
+

Мета данные

+
+
+ {# keywords #} + {% with field='keywords' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# title #} + {% with field='title' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# descriptions #} + {% with field='descriptions' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} +
+
+
+ + +
+ + +
+ + + + {# modal window #} +