From 87c0ebb2905cfab5b1f7043fbb4815edd93f8f72 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Sat, 27 Jan 2018 17:38:41 +0300 Subject: [PATCH 1/4] Add main page --- project/templates/lilcity/main.html | 575 ++++++++++++++++++++++++++++ project/urls.py | 2 +- web/build/img/sprite.svg | 0 3 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 project/templates/lilcity/main.html mode change 100755 => 100644 web/build/img/sprite.svg diff --git a/project/templates/lilcity/main.html b/project/templates/lilcity/main.html new file mode 100644 index 00000000..68994872 --- /dev/null +++ b/project/templates/lilcity/main.html @@ -0,0 +1,575 @@ +{% extends "templates/lilcity/index.html" %} {% load static %} + +{% block title %}School LIL.CITY{% endblock title %} +{% block content %} +
+
+
Первая онлайн-школа креативного мышления для детей! 5+
+ КУПИТЬ ДОСУП ЗА 2000р. в мес. +
+
+
+
+
+

Каждый день, с понедельника по пятницу в 17:00 по московскому времени мы встречаемся в прямом эфире.

+

Пять предметов на каждый день: Персонаж, Развитие креативного мышления, Акварель, Пластилиновая живопись и История + искусств.

+ +
+
О школе
+
+
+ +
+
+
+

С раннего возраста мы стремимся развить в детях креативность, умение думать и анализировать, работать в смешанных + техниках и всевозможными материалами. Каждый урок интересный и уникальный.

+

Для раскрытия творческого потенциала создаем благоприятные условия которые вдохновляют к развитию. Наша школа создает + необходимую среду, в которой маленькое семечко способностей и желания рисовать вырастет в могучее дерево безграничного + потенциала. +

+

Наши ученики становяться осознанными, уверенными и творческий личностями, способные решать сложные задачи благодаря + воображению. +

+
+
- Sasha Kru, CEO и основатель + Lil.City +
+ + + + + + +
Другие видео смотрите на нашем + канале +
+
+
+
+
+ +
+
ПРЯМОЙ ЭФИР
+
Каждый день в 17.00 (по Мск)
+
Кроме выходных. Запись эфира доступна в течение 24-х часов.
+
+ + + СМОТРЕТЬ ПРИМЕР ЭФИРА
+
+
+
+
+
Преимущества
+
+

Если цените время и стремитесь быть продуктивными, то онлайн-образование это выбор прогрессивного человека для достижения + необходимых результатов.

+ +
+
+
+
+ + + +
+
Доступность
+
Учитесь, не выходя из дома. С активной жизнью в больших городах, времени для образование остается не много. + Маленьким городам, наоборот, не хватает разнообразия мегаполисов.
+
+
+
+ + + +
+
Стоимость
+
Онлайн-образование дешевле. Здесь не требуется аренда помещения, нет коммунальных платежей.
+
+
+
+ + + +
+
Свобода перемещений
+
Это важный критерий для родителей. С онлайн-образованием собирать, одевать и стоять в бесконечных пробках теперь + не нужно.
+
+
+
+ + + +
+
Выбор преподавателя
+
Личные аккаунты Инстаграм также доступны, чтобы узнать о творчестве, мыслях и интересах. Принять решение у какого + преподавателя учиться теперь просто.
+
+
+
+

И, наконец, учиться онлайн можете в пижаме, без макияжа и с огурцами на лице!

+
+
+
+
+
+
Отзывы
+
Мы получаем сотни тёплых отзывов от довольных родителей. Их можно почитать + здесь;) +
+
+
+
+ +
+
+
@redanna333
+
Мой ребёнок зарисовал!!! Хотя, я и не ставила таких глобальных целей, участвуя в этом лагере, просто занять дитё + чем-то творческим хоть иногда, но он реально рисует, сам, и не надо приглашать и уговаривать, просто берёт и + рисует) Спасибо, Саша, от всей души) Надеемся на встречу в школе)
+
+
+
+
+ +
+
+
@redanna333
+
Саша, огромное спасибо за ещё одну возможность погружения в удивительный мир Ваших уроков! С начала первого летнего + лагеря и до сегодняшнего дня, был запущен творческий круговорот разных идей, по заданиям и просто так)). На самом + деле, удивительная способность, находясь далеко, по другую сторону экрана, создавать уникальный контакт присутствия + рядом, будто в одной комнате и давно знакомы). И ещё одно важное качество- быть на стороне ребёнка в непростом + творческом процессе- моя дочь, слушая Ваше задание, расправляет "крылья", не боясь оценочного мнения , а сосредоточившись + на задаче)). P.S В школу идём без сомнений!
+
+
+
+
+ +
+
+
@redanna333
+
Саша, 👋 Вы потрясающе четко и качественно можете объяснить задание урока! Дети настолько увлекаются процессом, + что взрослые и сами включаются в эту интересную игру ТВОРЧЕСТВО! Спасибо Вам за Вдохновение, Любовь и желание + творить Чудеса! Темыч теперь легко может начать рисовать "трудные" картинки, потому что тетя Саша сказала: "все + состоит из простых форм!" Теперь это наш девиз) главное ушёл страх, что не выйдет ПРАВИЛЬНО, потому что нет ограничений + и правил в творчестве😜🙌надеемся на скорую встречу!!!
+
+
+
+
+
+
+
+
Галерея
+
+

Тысячи шедевров уже созданы благодаря Lil City School. Более 10000 работ можно + увидеть в Инстаграм

+ +
+ +
+
+
+
+
+
ПРИЛОЖЕНИЯ LIL CITY
+
Лучшие работы попадают в приложение Lil World
+
Lil World – это арт-фото редактор многократно отмеченный AppStore по всему миру как лучшее приложение с огромной коллекцией + иллюстраций стикеров. Украшайте ваши фото и превращайте их в волшебные миры.
+ +
+
+
+ +
+
+
+
+
+
+
Преподаватели
+
+

Преподаватели Lil City School имеют большой опыт, поэтому с первых минут детям будет интересно с нами.

+ +
+
+
+
+ +
+
+
Саша Крю, + #lil_персонаж +
+
@sashakru
+
+

Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с крупнейшими российскими и зарубежными + издательствами.

+

Участник и победитель международных выставок.

+

Основатель компании "Lil City".

+
+
+
+
+
+ +
+
+
Саша Крю, + #lil_персонаж +
+
@sashakru
+
+

Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с крупнейшими российскими и зарубежными + издательствами.

+

Участник и победитель международных выставок.

+

Основатель компании "Lil City".

+
+
+
+
+
+ +
+
+
Саша Крю, + #lil_персонаж +
+
@sashakru
+
+

Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с крупнейшими российскими и зарубежными + издательствами.

+

Участник и победитель международных выставок.

+

Основатель компании "Lil City".

+
+
+
+
+
+ +
+
+
Саша Крю, + #lil_персонаж +
+
@sashakru
+
+

Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с крупнейшими российскими и зарубежными + издательствами.

+

Участник и победитель международных выставок.

+

Основатель компании "Lil City".

+
+
+
+
+
Если хотите к нам в команду, то ждем ваше резюме + на почту +
+
+
+
+
+
Расписание
+
+
+
Понедельник
+
+
Персонаж.
+
Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.
+
+ +
Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат + А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов + и клей-карандаш.
+
+
+
+
+
Вторник
+
+
Персонаж.
+
Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.
+
+ +
Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат + А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов + и клей-карандаш.
+
+
+
+
+
Среда
+
+
Персонаж.
+
Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.
+
+ +
Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат + А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов + и клей-карандаш.
+
+
+
+
+
Четверг
+
+
Персонаж.
+
Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.
+
+ +
Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат + А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов + и клей-карандаш.
+
+
+
+
+
Пятница
+
+
Персонаж.
+
Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.
+
+ +
Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат + А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов + и клей-карандаш.
+
+
+
+
+
+ Распечатать расписание чтобы не забыть
+
+
+
+
+
Онлайн-курсы
+
Помимо онлайн-школы Lil City у нас есть отдельные + курсы в записи. Учитесь и развивайте креативное мышление когда вам удобно.
+
+
+
+ + +
Подробнее
+
+
+
+ АНИМАЦИЯ +
30$
+
+ Базовый курс для детей по основам иллюстрации +
Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.
+
+
+ +
+
+
Александра Неимоверноумная
+
+
SEPT 12, 2017
+ +
+
+
+
+
+ + +
Подробнее
+
+
До запуска курса осталось:
+
16 часов 13 минут
+
+
+
+
+ АНИМАЦИЯ +
30$
+
+ Базовый курс для детей по основам иллюстрации +
Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.
+
+
+ +
+
+
Александра Неимоверноумная
+
+
SEPT 12, 2017
+ +
+
+
+
+
+ + +
Подробнее
+
+
+ АНИМАЦИЯ +
30$
+
+ Базовый курс для детей по основам иллюстрации +
Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.
+
+
+ +
+
+
Александра Неимоверноумная
+
+
SEPT 12, 2017
+ +
+
+
+
+
+ +
+
+
+
+
+
+
LILCITY
+
Приложения, развивающие игры и интерактивные книги от Lil City.
+ УЗНАТЬ БОЛЬШЕ +
+
+
+ +
+
+
+
+
Наши партнеры
+ +
+
+{% endblock content %} \ No newline at end of file diff --git a/project/urls.py b/project/urls.py index af884c32..ed5cd1dc 100644 --- a/project/urls.py +++ b/project/urls.py @@ -24,7 +24,7 @@ urlpatterns = [ path('admin/', admin.site.urls), path('auth/', include(('apps.auth.urls', 'lilcity'))), path('courses/', CoursesView.as_view(), name='courses'), - path('', TemplateView.as_view(template_name="templates/lilcity/index.html"), name='index'), + path('', TemplateView.as_view(template_name="templates/lilcity/main.html"), name='index'), ] diff --git a/web/build/img/sprite.svg b/web/build/img/sprite.svg old mode 100755 new mode 100644 From b9ef367c6d35f75d7ec3650684839d3b135a3edb Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Sat, 27 Jan 2018 19:09:51 +0300 Subject: [PATCH 2/4] Migrate to new user model --- apps/auth/views.py | 14 +++---- apps/user/admin.py | 7 ---- apps/user/migrations/0001_initial.py | 57 ++++++++++++++++---------- apps/user/models.py | 60 ++++++++++++++++------------ project/settings.py | 3 +- 5 files changed, 78 insertions(+), 63 deletions(-) diff --git a/apps/auth/views.py b/apps/auth/views.py index d1fcc322..f2ebcf18 100644 --- a/apps/auth/views.py +++ b/apps/auth/views.py @@ -13,7 +13,6 @@ from django.views.generic import FormView, View from django.views.generic.edit import BaseFormView from apps.notification.utils import send_email -from apps.user.models import LilcityUserSettings, LilcityUserProxy from .forms import LearnerRegistrationForm from .tokens import verification_email_token @@ -120,9 +119,9 @@ class FacebookLoginOrRegistration(View): except FacepyError: return JsonResponse({"success": False}) - facebook_id = data.get('id') + fb_id = data.get('id') - lilcity_user_settings = LilcityUserSettings.objects.filter(facebook_id=facebook_id) + lilcity_user_settings = User.objects.filter(fb_id=fb_id) if lilcity_user_settings.count(): login(requests, user=lilcity_user_settings[0].user) return JsonResponse({"success": True}) @@ -136,9 +135,8 @@ class FacebookLoginOrRegistration(View): first_name = data.get('first_name', '') last_name = data.get('last_name', '') - user = LilcityUserProxy.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=uuid4().hex) - - user.lilcity_user_settings.is_verification_email = True - user.lilcity_user_settings.facebook_id = facebook_id - user.lilcity_user_settings.save() + user = User.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=uuid4().hex) + user.is_email_proved = True + user.fb_id = fb_id + user.save() return JsonResponse({"success": True}) diff --git a/apps/user/admin.py b/apps/user/admin.py index 92876bde..694323fa 100644 --- a/apps/user/admin.py +++ b/apps/user/admin.py @@ -1,8 +1 @@ from django.contrib import admin - -from .models import LilcityUserSettings - - -@admin.register(LilcityUserSettings) -class LilcityUserSettingsAdmin(admin.ModelAdmin): - pass diff --git a/apps/user/migrations/0001_initial.py b/apps/user/migrations/0001_initial.py index 54aa1ab8..a2ed6c65 100644 --- a/apps/user/migrations/0001_initial.py +++ b/apps/user/migrations/0001_initial.py @@ -1,9 +1,10 @@ -# Generated by Django 2.0.1 on 2018-01-15 08:33 +# Generated by Django 2.0.1 on 2018-01-27 16:03 -import apps.user.models -from django.conf import settings +import django.contrib.auth.models +import django.contrib.auth.validators +import django.contrib.postgres.fields.jsonb from django.db import migrations, models -import django.db.models.deletion +import django.utils.timezone class Migration(migrations.Migration): @@ -12,33 +13,47 @@ class Migration(migrations.Migration): dependencies = [ ('auth', '0009_alter_user_last_name_max_length'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='LilcityUserSettings', + name='User', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('is_verification_email', models.BooleanField(default=False)), - ], - ), - migrations.CreateModel( - name='LilcityUserProxy', - fields=[ + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), + ('role', models.PositiveSmallIntegerField(choices=[(0, 'пользователь'), (1, 'автор'), (2, 'администратор')], default=0)), + ('gender', models.CharField(choices=[('n', 'не указан'), ('m', 'Мужчина'), ('f', 'Женщина')], max_length=1)), + ('country', models.CharField(default='', max_length=50)), + ('city', models.CharField(default='', max_length=85)), + ('about', models.CharField(default='', max_length=1000)), + ('instagram', models.URLField(default='')), + ('facebook', models.URLField(default='')), + ('twitter', models.URLField(default='')), + ('pinterest', models.URLField(default='')), + ('youtube', models.URLField(default='')), + ('vkontakte', models.URLField(default='')), + ('fb_id', models.PositiveIntegerField(blank=True, null=True, unique=True)), + ('fb_data', django.contrib.postgres.fields.jsonb.JSONField(default={})), + ('is_email_proved', models.BooleanField(default=False)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ - 'proxy': True, - 'indexes': [], + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, }, - bases=('auth.user',), managers=[ - ('objects', apps.user.models.LilcityUserManager()), + ('objects', django.contrib.auth.models.UserManager()), ], ), - migrations.AddField( - model_name='lilcityusersettings', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='lilcity_user_settings', to=settings.AUTH_USER_MODEL), - ), ] diff --git a/apps/user/models.py b/apps/user/models.py index 82ec3c6d..e568b7d9 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -1,27 +1,35 @@ from django.db import models -from django.contrib.auth import get_user_model -from django.contrib.auth.models import AbstractUser, UserManager - - -User = get_user_model() - - -class LilcityUserManager(UserManager): - def create_user(self, username, email=None, password=None, **extra_fields): - user = super().create_user(username, email, password, **extra_fields) - LilcityUserSettings.objects.create(user=user) - return user - - -class LilcityUserProxy(User): - objects = LilcityUserManager() - - class Meta: - proxy = True - - -class LilcityUserSettings(models.Model): - user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='lilcity_user_settings') - is_verification_email = models.BooleanField(default=False) - facebook_id = models.PositiveIntegerField(null=True, blank=True, unique=True) - +from django.contrib.auth.models import AbstractUser +from django.contrib.postgres import fields as pgfields +from django.utils.translation import gettext_lazy as _ + + +class User(AbstractUser): + ROLE_CHOICES = ( + (0, 'пользователь'), + (1, 'автор'), + (2, 'администратор'), + ) + GENDER_CHOICES = ( + ('n', 'не указан'), + ('m', 'Мужчина'), + ('f', 'Женщина'), + ) + email = models.EmailField(_('email address'), unique=True) + role = models.PositiveSmallIntegerField(default=0, choices=ROLE_CHOICES) + gender = models.CharField(max_length=1, choices=GENDER_CHOICES) + country = models.CharField(max_length=50, default='') + city = models.CharField(max_length=85, default='') + about = models.CharField(max_length=1000, default='') + instagram = models.URLField(default='') + facebook = models.URLField(default='') + twitter = models.URLField(default='') + pinterest = models.URLField(default='') + youtube = models.URLField(default='') + vkontakte = models.URLField(default='') + fb_id = models.PositiveIntegerField(null=True, blank=True, unique=True) + fb_data = pgfields.JSONField(default={}) + is_email_proved = models.BooleanField(default=False) + + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [] diff --git a/project/settings.py b/project/settings.py index 10946d9e..8ad324da 100644 --- a/project/settings.py +++ b/project/settings.py @@ -27,7 +27,6 @@ DEBUG = True ALLOWED_HOSTS = ["*"] # fixme: production mode - # Application definition INSTALLED_APPS = [ @@ -110,6 +109,8 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +AUTH_USER_MODEL = 'user.User' + # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ From bb390d608393a7f9a46a9053cb443306fb0d26b5 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Sat, 27 Jan 2018 19:16:47 +0300 Subject: [PATCH 3/4] Add verbose names for User fields --- apps/user/models.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/user/models.py b/apps/user/models.py index e568b7d9..9d129e61 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -16,20 +16,20 @@ class User(AbstractUser): ('f', 'Женщина'), ) email = models.EmailField(_('email address'), unique=True) - role = models.PositiveSmallIntegerField(default=0, choices=ROLE_CHOICES) - gender = models.CharField(max_length=1, choices=GENDER_CHOICES) - country = models.CharField(max_length=50, default='') - city = models.CharField(max_length=85, default='') - about = models.CharField(max_length=1000, default='') + role = models.PositiveSmallIntegerField('Роль', default=0, choices=ROLE_CHOICES) + gender = models.CharField('Пол', max_length=1, choices=GENDER_CHOICES) + country = models.CharField('Страна', max_length=50, default='') + city = models.CharField('Город', max_length=85, default='') + about = models.CharField('О себе', max_length=1000, default='') instagram = models.URLField(default='') facebook = models.URLField(default='') twitter = models.URLField(default='') pinterest = models.URLField(default='') youtube = models.URLField(default='') - vkontakte = models.URLField(default='') + vkontakte = models.URLField('ВКонтакте', default='') fb_id = models.PositiveIntegerField(null=True, blank=True, unique=True) fb_data = pgfields.JSONField(default={}) - is_email_proved = models.BooleanField(default=False) + is_email_proved = models.BooleanField('Верифицирован по email', default=False) USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] From e0c3862e8cfd533c8c416a8f4c5395df583e6405 Mon Sep 17 00:00:00 2001 From: Ivlev Denis Date: Sun, 28 Jan 2018 09:47:17 +0300 Subject: [PATCH 4/4] Fix User REQUIRED_FIELDS --- apps/user/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/user/models.py b/apps/user/models.py index 9d129e61..c0aac8ca 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -1,5 +1,5 @@ from django.db import models -from django.contrib.auth.models import AbstractUser +from django.contrib.auth.models import AbstractUser, UserManager from django.contrib.postgres import fields as pgfields from django.utils.translation import gettext_lazy as _ @@ -32,4 +32,4 @@ class User(AbstractUser): is_email_proved = models.BooleanField('Верифицирован по email', default=False) USERNAME_FIELD = 'email' - REQUIRED_FIELDS = [] + REQUIRED_FIELDS = ['username']