Merge remote-tracking branch 'origin/dev' into dev

remotes/origin/hasaccess
Vitaly Baev 8 years ago
commit bbf5df952e
  1. 3
      .gitignore
  2. 31
      apps/auth/views.py
  3. 11
      apps/course/admin.py
  4. 11
      apps/course/filters.py
  5. 285
      apps/course/fixtures/course.json
  6. 73
      apps/course/migrations/0002_auto_20180126_1325.py
  7. 25
      apps/course/migrations/0003_auto_20180126_1347.py
  8. 43
      apps/course/models.py
  9. 12
      apps/course/templates/course/_items.html
  10. 5
      apps/course/templates/course/inclusion/category_menu_items.html
  11. 8
      apps/course/templatetags/lilcity_category.py
  12. 6
      apps/course/views.py
  13. 7
      apps/user/admin.py
  14. 34
      apps/user/fixtures/superuser.json
  15. 57
      apps/user/migrations/0001_initial.py
  16. 58
      apps/user/models.py
  17. 21
      docker-compose.yml
  18. BIN
      media/courses/pic-1_sTaZawQ.jpg
  19. 20
      project/settings.py
  20. 34
      project/templates/lilcity/index.html
  21. 575
      project/templates/lilcity/main.html
  22. 2
      project/urls.py
  23. 2
      requirements.txt
  24. 0
      web/build/img/sprite.svg

3
.gitignore vendored

@ -110,4 +110,5 @@ venv.bak/
# JavaScript
.map
node_modules
db.sqlite3
db.sqlite3
.vscode

@ -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
@ -30,7 +29,19 @@ class LearnerRegistrationView(FormView):
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = User.objects.create_user(username=email, email=email, first_name=first_name, last_name=last_name, password=password)
user, created = User.objects.get_or_create(
username=email, email=email,
first_name=first_name, last_name=last_name
)
if not created:
return JsonResponse({
"success": False,
'errors': {'__all__': [{'message': 'Возможно вы уже зарегистрированы?'}]}
}, status=400)
user.set_password(password)
user.save()
login(self.request, user)
# fixme: change email text
@ -64,7 +75,8 @@ class LoginView(FormView):
class VerificationEmailView(View):
def get(self, request, *args, **kwargs):
is_valid_token = verification_email_token.check_token(request.user, kwargs.get('token'))
is_valid_token = verification_email_token.check_token(
request.user, kwargs.get('token'))
if is_valid_token:
lilcity_user_settings = request.user.lilcity_user_settings
@ -120,9 +132,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 +148,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})

@ -5,7 +5,16 @@ from .models import Course, Category
@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
pass
list_display = (
'author',
'title',
'price',
'is_infinite',
'category',
'status',
'created_at',
'update_at',
)
@admin.register(Category)

@ -0,0 +1,11 @@
import django_filters
from .models import Course
class CourseFilter(django_filters.FilterSet):
category = django_filters.CharFilter(field_name='category__title', lookup_expr='iexact')
class Meta:
model = Course
fields = ['category']

@ -0,0 +1,285 @@
[
{
"model": "course.course",
"pk": 1,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 2,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:04:41.113Z",
"update_at": "2018-01-27T07:12:04.168Z"
}
},
{
"model": "course.course",
"pk": 2,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 1,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.437Z",
"update_at": "2018-01-27T07:11:55.373Z"
}
},
{
"model": "course.course",
"pk": 3,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 9,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.442Z",
"update_at": "2018-01-27T07:11:43.838Z"
}
},
{
"model": "course.course",
"pk": 4,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 8,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.445Z",
"update_at": "2018-01-27T07:11:35.342Z"
}
},
{
"model": "course.course",
"pk": 5,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 7,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.449Z",
"update_at": "2018-01-27T07:11:26.725Z"
}
},
{
"model": "course.course",
"pk": 6,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 6,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.452Z",
"update_at": "2018-01-27T07:11:15.061Z"
}
},
{
"model": "course.course",
"pk": 7,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 5,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.455Z",
"update_at": "2018-01-27T07:11:03.583Z"
}
},
{
"model": "course.course",
"pk": 8,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 4,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.458Z",
"update_at": "2018-01-27T07:10:52.322Z"
}
},
{
"model": "course.course",
"pk": 9,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 3,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.461Z",
"update_at": "2018-01-27T07:10:42.721Z"
}
},
{
"model": "course.course",
"pk": 10,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 2,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.464Z",
"update_at": "2018-01-27T07:10:33.374Z"
}
},
{
"model": "course.course",
"pk": 11,
"fields": {
"author": 1,
"title": "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u0443\u0440\u0441 \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u0439 \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043c \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438",
"short_description": "\u042d\u0442\u043e\u0442 \u043a\u0443\u0440\u0441 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u0442\u044f\u043c \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u0435\u043b\u044b\u0439 \u0438 \u0445\u0430\u0440\u0438\u0437\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439.",
"cover": "courses/pic-1_sTaZawQ.jpg",
"price": "50.00",
"is_infinite": false,
"deferred_start_at": null,
"category": 1,
"duration": 1,
"is_featured": false,
"url": "https://gitlab.com/",
"status": 0,
"created_at": "2018-01-27T07:09:03.467Z",
"update_at": "2018-01-27T07:09:03.467Z"
}
},
{
"model": "course.category",
"pk": 1,
"fields": {
"title": "\u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436"
}
},
{
"model": "course.category",
"pk": 2,
"fields": {
"title": "\u0430\u043a\u0432\u0430\u0440\u0435\u043b\u044c"
}
},
{
"model": "course.category",
"pk": 3,
"fields": {
"title": "\u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f"
}
},
{
"model": "course.category",
"pk": 4,
"fields": {
"title": "\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f"
}
},
{
"model": "course.category",
"pk": 5,
"fields": {
"title": "\u043f\u0430\u0441\u0442\u0435\u043b\u044c"
}
},
{
"model": "course.category",
"pk": 6,
"fields": {
"title": "\u043f\u043b\u0430\u0441\u0442\u0438\u043b\u0438\u043d"
}
},
{
"model": "course.category",
"pk": 7,
"fields": {
"title": "\u043a\u0440\u0435\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435"
}
},
{
"model": "course.category",
"pk": 8,
"fields": {
"title": "\u043c\u043e\u0442\u043e\u0440\u0438\u043a\u0430"
}
},
{
"model": "course.category",
"pk": 9,
"fields": {
"title": "\u0436\u0438\u0432\u043e\u043f\u0438\u0441\u044c"
}
}
]

@ -0,0 +1,73 @@
# Generated by Django 2.0.1 on 2018-01-26 13:25
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('course', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='category',
options={'verbose_name': 'Категория', 'verbose_name_plural': 'Категории'},
),
migrations.AlterModelManagers(
name='category',
managers=[
],
),
migrations.RenameField(
model_name='course',
old_name='background',
new_name='cover',
),
migrations.RenameField(
model_name='course',
old_name='deferred_start',
new_name='deferred_start_at',
),
migrations.RenameField(
model_name='course',
old_name='is_highlighted',
new_name='is_featured',
),
migrations.RemoveField(
model_name='course',
name='created_at',
),
migrations.RemoveField(
model_name='course',
name='update_at',
),
migrations.AddField(
model_name='course',
name='author',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='course',
name='duration',
field=models.IntegerField(default=0, verbose_name='Продолжительность курса'),
),
migrations.AddField(
model_name='course',
name='is_infinite',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='course',
name='status',
field=models.PositiveSmallIntegerField(choices=[(0, 'Pending'), (1, 'Published'), (2, 'Archived')], default=0, verbose_name='Статус'),
),
migrations.AddField(
model_name='course',
name='url',
field=models.URLField(default='', verbose_name='Ссылка'),
),
]

@ -0,0 +1,25 @@
# Generated by Django 2.0.1 on 2018-01-26 13:47
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('course', '0002_auto_20180126_1325'),
]
operations = [
migrations.AddField(
model_name='course',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='course',
name='update_at',
field=models.DateTimeField(auto_now=True),
),
]

@ -1,32 +1,55 @@
import arrow
from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
from .manager import CategoryQuerySet
User = get_user_model()
class Course(models.Model):
STATUS_CHOICES = (
(0, 'Pending'),
(1, 'Published'),
(2, 'Archived'),
)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
title = models.CharField("Название курса", max_length=100)
short_description = models.TextField("Краткое описание курса")
background = models.ImageField("Фон курса", upload_to='courses')
cover = models.ImageField("Фон курса", upload_to='courses')
price = models.DecimalField("Цена курса", help_text="Если цены нету, то курс бесплатный", max_digits=10, decimal_places=2, null=True, blank=True)
is_highlighted = models.BooleanField(default=False)
deferred_start = models.DateTimeField("Отложенный запуск курса", help_text="Заполнить если курс отложенный", null=True, blank=True)
is_infinite = models.BooleanField(default=False)
deferred_start_at = models.DateTimeField("Отложенный запуск курса", help_text="Заполнить если курс отложенный", null=True, blank=True)
category = models.ForeignKey("Category", on_delete=models.PROTECT)
duration = models.IntegerField("Продолжительность курса", default=0)
is_featured = models.BooleanField(default=False)
url = models.URLField('Ссылка', default='')
status = models.PositiveSmallIntegerField('Статус', default=0, choices=STATUS_CHOICES)
created_at = models.DateTimeField(auto_created=True)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
@property
def is_free(self):
if self.price:
return False
return True
@property
def deferred_start_at_humanize(self):
return arrow.get(self.deferred_start_at).humanize(locale='ru')
@property
def created_at_humanize(self):
return arrow.get(self.created_at).humanize(locale='ru')
@property
def is_deferred_start(self):
if not self.deferred_start:
if not self.deferred_start_at:
return False
if timezone.now() < self.deferred_start:
if timezone.now() < self.deferred_start_at:
return True
return False
@ -38,7 +61,9 @@ class Course(models.Model):
class Category(models.Model):
title = models.CharField("Название категории", max_length=100)
manager = CategoryQuerySet.as_manager()
def __str__(self):
return self.title
class Meta:
verbose_name = "Категория"
verbose_name_plural = "Категории"

@ -1,19 +1,19 @@
{% load static %}
<div class="courses__item"><a class="courses__preview" href="#"><img class="courses__pic" src="{% get_media_prefix %}{{ course.background }}"/>
<div class="courses__item"><a class="courses__preview" href="#"><img class="courses__pic" src="{{ course.cover.url }}"/>
<div class="courses__view">Подробнее</div>
{% if course.is_highlighted %}
{% if course.is_featured %}
<div class="courses__label courses__label_fav"></div>
{% endif %}
{% if course.is_deferred_start %}
<div class="courses__soon">
<div class="courses__left">До запуска курса осталось:</div>
<div class="courses__time">16 часов 13 минут</div>
<div class="courses__time">{{ course.deferred_start_at_humanize }}</div>
</div>
<div class="courses__label courses__label_clock"></div>
{% endif %}
</a>
<div class="courses__details"><a class="courses__theme theme {{ theme_color }}" href="#">АНИМАЦИЯ</a>
<div class="courses__details"><a class="courses__theme theme {{ theme_color }}" href="#">{{ course.category | upper }}</a>
{% if not course.is_free %}<div class="courses__price">{{ course.price|floatformat:"-2" }}$</div>{% endif %}
</div>
<a class="courses__title" href="#">{{ course.title }}</a>
@ -22,9 +22,9 @@
<div class="courses__user user">
<div class="user__ava ava"><img class="ava__pic" src={% static "img/user.jpg" %}/></div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__name">{{ course.author.first_name }} {{ course.author.last_name }}</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<div class="user__date">{{ course.created_at_humanize }}</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">

@ -0,0 +1,5 @@
{% for category in category_items %}
<a class="header__link" href="{% url 'courses' %}?category={{ category.title }}">
<div class="header__title">{{ category.title }}</div>
</a>
{% endfor %}

@ -2,10 +2,14 @@ from django import template
from ..models import Category
register = template.Library()
@register.inclusion_tag('course/inclusion/category_items.html')
def category_items():
return {"category_items": Category.manager.all()}
return {"category_items": Category.objects.all()}
@register.inclusion_tag('course/inclusion/category_menu_items.html')
def category_menu_items():
return {"category_items": Category.objects.all()}

@ -1,6 +1,7 @@
from django.views.generic import ListView
from .models import Course
from .filters import CourseFilter
class CoursesView(ListView):
@ -8,6 +9,11 @@ class CoursesView(ListView):
context_object_name = "course_items"
paginate_by = 6
def get_queryset(self):
queryset = super().get_queryset()
filtered = CourseFilter(self.request.GET, queryset=queryset)
return filtered.qs
def get_template_names(self):
if self.request.is_ajax():
return 'course/course_items.html'

@ -1,8 +1 @@
from django.contrib import admin
from .models import LilcityUserSettings
@admin.register(LilcityUserSettings)
class LilcityUserSettingsAdmin(admin.ModelAdmin):
pass

@ -0,0 +1,34 @@
[
{
"model": "user.user",
"pk": 1,
"fields": {
"password": "pbkdf2_sha256$100000$HoGxjmAQy4yo$3u+CrUiFtooddpg16OEUaSSjqUlwgFUBP1gt75hEoJs=",
"last_login": "2018-01-28T08:41:44.702Z",
"is_superuser": true,
"username": "admin@lil.city",
"first_name": "",
"last_name": "",
"is_staff": true,
"is_active": true,
"date_joined": "2018-01-28T08:41:19.690Z",
"email": "admin@lil.city",
"role": 0,
"gender": "",
"country": "",
"city": "",
"about": "",
"instagram": "",
"facebook": "",
"twitter": "",
"pinterest": "",
"youtube": "",
"vkontakte": "",
"fb_id": null,
"fb_data": {},
"is_email_proved": false,
"groups": [],
"user_permissions": []
}
}
]

@ -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),
),
]

@ -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.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('Верифицирован по email', default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

@ -1,20 +1,29 @@
version: '3'
services:
postgres:
image: postgres:9.6
db:
image: postgres:10-alpine
environment:
- POSTGRES_PASSWORD=1234
- POSTGRES_USER=postgres
- LANG=ru_RU.UTF-8
- POSTGRES_DB=lilcity
- POSTGRES_USER=lilcity
- POSTGRES_PASSWORD=GPVs/E/{5&qe
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- "5432:5432"
web:
build: .
restart: always
volumes:
- .:/lilcity
command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
command: bash -c "python manage.py migrate && python manage.py loaddata /lilcity/apps/*/fixtures/*.json && python manage.py runserver 0.0.0.0:8000"
environment:
- DJANGO_SETTINGS_MODULE=project.settings
- DATABASE_SERVICE_HOST=db
ports:
- "8000:8000"
depends_on:
- postgres
- db
links:
- db

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -27,7 +27,6 @@ DEBUG = True
ALLOWED_HOSTS = ["*"] # fixme: production mode
# Application definition
INSTALLED_APPS = [
@ -40,6 +39,7 @@ INSTALLED_APPS = [
] + [
'anymail',
'active_link',
'django_filters',
] + [
'apps.auth.apps',
'apps.user',
@ -84,14 +84,24 @@ WSGI_APPLICATION = 'project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'lilcity',
'USER': 'lilcity',
'PASSWORD': 'GPVs/E/{5&qe',
'HOST': os.getenv('DATABASE_SERVICE_HOST', '127.0.0.1'),
'PORT': 5432,
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
@ -110,6 +120,8 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
AUTH_USER_MODEL = 'user.User'
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

@ -1,12 +1,16 @@
{% load static %}
{% load active_link_tags %}
{% load category_menu_items from lilcity_category %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index Page</title>
<title>
{% block title %}Онлайн-курсы LilCity{% endblock title%}
</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="theme-color" content="#fff">
@ -108,33 +112,7 @@
</div>
<div class="header__group"><a class="header__section header__section_sub js-header-section {% active_link 'courses' %}" href="{% url 'courses' %}">ВИДЕО-КУРСЫ</a>
<div class="header__list js-header-list">
<a class="header__link" href="#">
<div class="header__title">ПЕРСОНАЖ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АКВАРЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ИЛЛЮСТРАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">АНИМАЦИЯ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПАСТЕЛЬ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ПЛАСТИЛИН</div>
</a>
<a class="header__link" href="#">
<div class="header__title">КРЕАТИВНОЕ МЫШЛЕНИЕ</div>
</a>
<a class="header__link" href="#">
<div class="header__title">МОТОРИКА</div>
</a>
<a class="header__link" href="#">
<div class="header__title">ЖИВОПИСЬ</div>
</a>
{% category_menu_items %}
</div>
</div>
<div class="header__group"><a class="header__section" href="#">БЛОГ</a></div>

@ -0,0 +1,575 @@
{% extends "templates/lilcity/index.html" %} {% load static %}
{% block title %}School LIL.CITY{% endblock title %}
{% block content %}
<div class="main" style="background-image: url({% static 'img/bg-1.jpg' %});">
<div class="main__center center">
<div class="main__title">Первая онлайн-школа креативного мышления для детей! 5+</div>
<a class="main__btn btn" href="#">КУПИТЬ ДОСУП ЗА 2000р. в мес.</a>
</div>
</div>
<div class="section">
<div class="section__center center">
<div class="text text_lg">
<p>Каждый день, с понедельника по пятницу в 17:00 по московскому времени мы встречаемся в прямом эфире. </p>
<p>Пять предметов на каждый день: Персонаж, Развитие креативного мышления, Акварель, Пластилиновая живопись и История
искусств. </p>
<img class="text__curve text__curve_one" src="{% static 'img/curve-1.svg' %}" width="320">
</div>
<div class="title title_center">О школе</div>
<div class="about">
<div class="about__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="about__wrap">
<div class="about__content">
<p>С раннего возраста мы стремимся развить в детях креативность, умение думать и анализировать, работать в смешанных
техниках и всевозможными материалами. Каждый урок интересный и уникальный.</p>
<p>Для раскрытия творческого потенциала создаем благоприятные условия которые вдохновляют к развитию. Наша школа создает
необходимую среду, в которой маленькое семечко способностей и желания рисовать вырастет в могучее дерево безграничного
потенциала.
</p>
<p>Наши ученики становяться осознанными, уверенными и творческий личностями, способные решать сложные задачи благодаря
воображению.
</p>
</div>
<div class="about__ceo">- Sasha Kru, CEO и основатель
<a href='#'>Lil.City</a>
</div>
<a class="about__video video" href="#">
<img class="video__pic" src="{% static 'img/video-1.jpg' %}">
<svg class="icon icon-play">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use>
</svg>
</a>
<div class="about__more">Другие видео смотрите на нашем
<a href='#'>канале</a>
</div>
</div>
</div>
</div>
</div>
<a class="online" href="#" style="background-image: url({% static 'img/video-1.jpg' %});">
<div class="online__center center">
<div class="online__type">ПРЯМОЙ ЭФИР</div>
<div class="online__title">Каждый день в 17.00 (по Мск) </div>
<div class="online__text text">Кроме выходных. Запись эфира доступна в&nbsp;течение 24-х&nbsp;часов.</div>
<div class="online__action">
<svg class="icon icon-play">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-play"></use>
</svg>СМОТРЕТЬ ПРИМЕР ЭФИРА</div>
</div>
</a>
<div class="section">
<div class="section__center center">
<div class="title title_center">Преимущества</div>
<div class="text">
<p>Если цените время и стремитесь быть продуктивными, то онлайн-образование это выбор прогрессивного человека для достижения
необходимых результатов.</p>
<img class="text__curve text__curve_two" src="{% static 'img/curve-2.svg' %}" width="211">
</div>
<div class="benefits">
<div class="benefits__item">
<div class="benefits__preview">
<svg class="icon icon-thumb">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-thumb"></use>
</svg>
</div>
<div class="benefits__title">Доступность</div>
<div class="benefits__content">Учитесь, не выходя из дома. С&nbsp;активной жизнью в больших городах, времени для образование остается не много.
Маленьким городам, наоборот, не хватает разнообразия мегаполисов.</div>
</div>
<div class="benefits__item">
<div class="benefits__preview">
<svg class="icon icon-wallet">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-wallet"></use>
</svg>
</div>
<div class="benefits__title">Стоимость</div>
<div class="benefits__content">Онлайн-образование дешевле. Здесь не требуется аренда помещения, нет коммунальных платежей.</div>
</div>
<div class="benefits__item">
<div class="benefits__preview">
<svg class="icon icon-location">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-location"></use>
</svg>
</div>
<div class="benefits__title">Свобода перемещений</div>
<div class="benefits__content">Это важный критерий для родителей. С онлайн-образованием собирать, одевать и стоять в бесконечных пробках теперь
не нужно.</div>
</div>
<div class="benefits__item">
<div class="benefits__preview">
<svg class="icon icon-searching">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-searching"></use>
</svg>
</div>
<div class="benefits__title">Выбор преподавателя </div>
<div class="benefits__content">Личные аккаунты Инстаграм также доступны, чтобы узнать о творчестве, мыслях и интересах. Принять решение у какого
преподавателя учиться теперь просто.</div>
</div>
</div>
<div class="text text_mb0">
<p>И, наконец, учиться онлайн можете в пижаме, без макияжа и с огурцами на лице!</p>
</div>
</div>
</div>
<div class="section section_review">
<div class="section__center center center_md">
<div class="title title_center">Отзывы</div>
<div class="text">Мы получаем сотни тёплых отзывов от довольных родителей. Их можно почитать
<a href="#">здесь;)</a>
</div>
<div class="reviews">
<div class="reviews__item">
<div class="reviews__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="reviews__wrap">
<div class="reviews__name">@redanna333</div>
<div class="reviews__content">Мой ребёнок зарисовал!!! Хотя, я и не ставила таких глобальных целей, участвуя в этом лагере, просто занять дитё
чем-то творческим хоть иногда, но он реально рисует, сам, и не надо приглашать и уговаривать, просто берёт и
рисует) Спасибо, Саша, от всей души) Надеемся на встречу в школе)</div>
</div>
</div>
<div class="reviews__item">
<div class="reviews__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="reviews__wrap">
<div class="reviews__name">@redanna333</div>
<div class="reviews__content">Саша, огромное спасибо за ещё одну возможность погружения в удивительный мир Ваших уроков! С начала первого летнего
лагеря и до сегодняшнего дня, был запущен творческий круговорот разных идей, по заданиям и просто так)). На самом
деле, удивительная способность, находясь далеко, по другую сторону экрана, создавать уникальный контакт присутствия
рядом, будто в одной комнате и давно знакомы). И ещё одно важное качество- быть на стороне ребёнка в непростом
творческом процессе- моя дочь, слушая Ваше задание, расправляет "крылья", не боясь оценочного мнения , а сосредоточившись
на задаче)). P.S В школу идём без сомнений!</div>
</div>
</div>
<div class="reviews__item">
<div class="reviews__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="reviews__wrap">
<div class="reviews__name">@redanna333</div>
<div class="reviews__content">Саша, 👋 Вы потрясающе четко и качественно можете объяснить задание урока! Дети настолько увлекаются процессом,
что взрослые и сами включаются в эту интересную игру ТВОРЧЕСТВО! Спасибо Вам за Вдохновение, Любовь и желание
творить Чудеса! Темыч теперь легко может начать рисовать "трудные" картинки, потому что тетя Саша сказала: "все
состоит из простых форм!" Теперь это наш девиз) главное ушёл страх, что не выйдет ПРАВИЛЬНО, потому что нет ограничений
и правил в творчестве😜🙌надеемся на скорую встречу!!!</div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<div class="section__center center">
<div class="title title_center">Галерея</div>
<div class="text">
<p>Тысячи шедевров уже созданы благодаря Lil City School. Более 10000 работ можно
<a href='#'>увидеть</a> в Инстаграм</p>
<img class="text__curve text__curve_three" src="{% static 'img/curve-3.svg' %}">
</div>
<div class="gallery">
<div class="gallery__grid">
<div class="gallery__item gallery__item_lg">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
</div>
<div class="gallery__grid">
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item gallery__item_lg">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
<div class="gallery__item">
<img class="gallery__pic" src="{% static 'img/box.jpg' %}">
</div>
</div>
</div>
</div>
</div>
<div class="app">
<div class="app__center center">
<div class="app__col">
<div class="app__theme">ПРИЛОЖЕНИЯ LIL CITY</div>
<div class="app__title">Лучшие работы попадают в приложение Lil World</div>
<div class="app__content">Lil World – это арт-фото редактор многократно отмеченный AppStore по всему миру как лучшее приложение с огромной коллекцией
иллюстраций стикеров. Украшайте ваши фото и превращайте их в волшебные миры.</div>
<div class="app__links">
<a class="app__link" href="#">
<img class="app__pic" src="{% static 'img/app-store.svg' %}">
</a>
<a class="app__link" href="#">
<img class="app__pic" src="{% static 'img/google-play.svg' %}">
</a>
</div>
</div>
<div class="app__col">
<div class="app__preview">
<img class="app__pic" src="{% static 'img/screens.png' %}">
</div>
</div>
</div>
</div>
<div class="section">
<div class="section__center center center_md">
<div class="title title_center">Преподаватели</div>
<div class="text">
<p>Преподаватели Lil City School имеют большой опыт, поэтому с первых минут детям будет интересно с нами.</p>
<img class="text__curve text__curve_three" src="{% static 'img/curve-3.svg' %}">
</div>
<div class="teachers">
<div class="teachers__item">
<div class="teachers__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="teachers__wrap">
<div class="teachers__title">Саша Крю,
<a href='#'>#lil_персонаж</a>
</div>
<div class="teachers__name">@sashakru</div>
<div class="teachers__content">
<p>Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с&nbsp;крупнейшими российскими и зарубежными
издательствами. </p>
<p>Участник и победитель международных выставок. </p>
<p>Основатель компании "Lil City".</p>
</div>
</div>
</div>
<div class="teachers__item">
<div class="teachers__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="teachers__wrap">
<div class="teachers__title">Саша Крю,
<a href='#'>#lil_персонаж</a>
</div>
<div class="teachers__name">@sashakru</div>
<div class="teachers__content">
<p>Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с&nbsp;крупнейшими российскими и зарубежными
издательствами. </p>
<p>Участник и победитель международных выставок. </p>
<p>Основатель компании "Lil City".</p>
</div>
</div>
</div>
<div class="teachers__item">
<div class="teachers__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="teachers__wrap">
<div class="teachers__title">Саша Крю,
<a href='#'>#lil_персонаж</a>
</div>
<div class="teachers__name">@sashakru</div>
<div class="teachers__content">
<p>Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с&nbsp;крупнейшими российскими и зарубежными
издательствами. </p>
<p>Участник и победитель международных выставок. </p>
<p>Основатель компании "Lil City".</p>
</div>
</div>
</div>
<div class="teachers__item">
<div class="teachers__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="teachers__wrap">
<div class="teachers__title">Саша Крю,
<a href='#'>#lil_персонаж</a>
</div>
<div class="teachers__name">@sashakru</div>
<div class="teachers__content">
<p>Закончила ПХУ им К.А.Савицкого художник театра и кино. Работала с&nbsp;крупнейшими российскими и зарубежными
издательствами. </p>
<p>Участник и победитель международных выставок. </p>
<p>Основатель компании "Lil City".</p>
</div>
</div>
</div>
</div>
<div class="text text_mb0">Если хотите к нам в команду, то ждем ваше резюме
<a href='#'>на&nbsp;почту</a>
</div>
</div>
</div>
<div class="section section_gray">
<div class="section__center center center_md">
<div class="title title_center">Расписание</div>
<div class="schedule">
<div class="schedule__item">
<div class="schedule__day">Понедельник</div>
<div class="schedule__wrap">
<div class="schedule__title">Персонаж.</div>
<div class="schedule__content">Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.</div>
<div class="schedule__toggle toggle">
<button class="toggle__head js-toggle-head">Материалы
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
<div class="toggle__body">Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат
А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов
и клей-карандаш.</div>
</div>
</div>
</div>
<div class="schedule__item">
<div class="schedule__day">Вторник</div>
<div class="schedule__wrap">
<div class="schedule__title">Персонаж.</div>
<div class="schedule__content">Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.</div>
<div class="schedule__toggle toggle">
<button class="toggle__head js-toggle-head">Материалы
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
<div class="toggle__body">Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат
А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов
и клей-карандаш.</div>
</div>
</div>
</div>
<div class="schedule__item">
<div class="schedule__day">Среда</div>
<div class="schedule__wrap">
<div class="schedule__title">Персонаж.</div>
<div class="schedule__content">Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.</div>
<div class="schedule__toggle toggle">
<button class="toggle__head js-toggle-head">Материалы
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
<div class="toggle__body">Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат
А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов
и клей-карандаш.</div>
</div>
</div>
</div>
<div class="schedule__item">
<div class="schedule__day">Четверг</div>
<div class="schedule__wrap">
<div class="schedule__title">Персонаж.</div>
<div class="schedule__content">Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.</div>
<div class="schedule__toggle toggle">
<button class="toggle__head js-toggle-head">Материалы
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
<div class="toggle__body">Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат
А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов
и клей-карандаш.</div>
</div>
</div>
</div>
<div class="schedule__item">
<div class="schedule__day">Пятница</div>
<div class="schedule__wrap">
<div class="schedule__title">Персонаж.</div>
<div class="schedule__content">Учимся создавать персонажей из простых форм. Изучаем характеры и эмоции.</div>
<div class="schedule__toggle toggle">
<button class="toggle__head js-toggle-head">Материалы
<svg class="icon icon-arrow-down">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use>
</svg>
</button>
<div class="toggle__body">Cамое главное - иметь альбом или блокнот с пустыми страницами (без линий и клеток) плотной гладкой бумагой, формат
А4. Рисовать будем цветными карандашами, а также простым, мягкостью B2. Иногда пригодятся вырезки из журналов
и клей-карандаш.</div>
</div>
</div>
</div>
</div>
<div class="text text_mb0">
<a href='#'>Распечатать расписание</a> чтобы не забыть</div>
</div>
</div>
<div class="section">
<div class="section__center center">
<div class="title title_center">Онлайн-курсы</div>
<div class="text">Помимо онлайн-школы Lil City у нас есть отдельные
<a href='#'>курсы в записи</a>. Учитесь и развивайте креативное мышление когда вам удобно.</div>
<div class="courses">
<div class="courses__list">
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
<div class="courses__label courses__label_fav"></div>
</a>
<div class="courses__details">
<a class="courses__theme theme" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
<div class="courses__soon">
<div class="courses__left">До запуска курса осталось:</div>
<div class="courses__time">16 часов 13 минут</div>
</div>
<div class="courses__label courses__label_clock"></div>
</a>
<div class="courses__details">
<a class="courses__theme theme theme_green" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="courses__item">
<a class="courses__preview" href="#">
<img class="courses__pic" src="{% static 'img/pic-1.jpg' %}" />
<div class="courses__view">Подробнее</div>
</a>
<div class="courses__details">
<a class="courses__theme theme theme_violet" href="#">АНИМАЦИЯ</a>
<div class="courses__price">30$</div>
</div>
<a class="courses__title" href="#">Базовый курс для детей по основам иллюстрации</a>
<div class="courses__content">Этот курс поможет детям узнать о том как из простых форм создавать веселый и харизматичных персонажей.</div>
<div class="courses__user user">
<div class="user__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}" />
</div>
<div class="user__info">
<div class="user__name">Александра Неимоверноумная</div>
<div class="user__meta">
<div class="user__date">SEPT 12, 2017</div>
<a class="user__likes likes" href="#">
<div class="likes__counter">253</div>
<div class="likes__icon">
<svg class="icon icon-like">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like"></use>
</svg>
<svg class="icon icon-like-fill">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-like-fill"></use>
</svg>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="courses__more more">
<a class="more__btn btn btn_light" href="#">УЗНАТЬ ПОДРОБНЕЕ</a>
</div>
</div>
</div>
</div>
<div class="game">
<div class="game__center center">
<div class="game__wrap">
<div class="game__theme">LILCITY</div>
<div class="game__title">Приложения, развивающие игры и интерактивные книги от Lil City.</div>
<a class="game__btn btn btn_dark" href="#">УЗНАТЬ БОЛЬШЕ</a>
</div>
</div>
<div class="game__preview">
<img class="game__pic" src="{% static 'img/icons.png' %}">
</div>
</div>
<div class="section">
<div class="section__center center">
<div class="title title_center">Наши партнеры</div>
<div class="partners">
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
<a class="partners__item" href="#">
<img class="partners__pic" src="{% static 'img/box.jpg' %}">
</a>
</div>
</div>
</div>
{% endblock content %}

@ -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'),
]

@ -7,3 +7,5 @@ psycopg2==2.7.3.2
facepy==1.0.9
Pillow==5.0.0
django-active-link==0.1.2
arrow==0.12.1
django-filter==2.0.0.dev1

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Loading…
Cancel
Save