commit
6926b4c694
38 changed files with 797 additions and 279 deletions
@ -1,27 +1,11 @@ |
|||||||
#**SkillBox LMS** |
#**SkillBox LMS** |
||||||
|
|
||||||
Подробные шаги для проверки работоспособности CI |
Нужно выполнить миграции и запустить скрипт update_db.py без параметров в модуле courses (скрипт на всякий случай пока не удалять) |
||||||
|
|
||||||
1) Проверяем доступ к репозиторию кода https://gitlab.com/skillbox/go.skillbox.ru |
Фактически в структуре данных изменилось только то, что появилась новая табличка NormalMap. Скрипт собирает все treeview курсов и кладёт в эту табличку |
||||||
2) Клонируем проект |
|
||||||
3) Вносим изменения в код |
|
||||||
4) Комитим изменения в новый branch (ОБЯЗАТЕЛЬНО в отдельный Branch) |
|
||||||
4.1) Пушим изменения |
|
||||||
5) Ждем выполнения создания тестового сайта https://gitlab.com/skillbox/go.skillbox.ru/pipelines |
|
||||||
6) Сайт будет доступен по адресу <branch_name>.lms.test.spicycms.com |
|
||||||
|
|
||||||
**Правила для разработчика** |
Появилась новая зависимость django_rest_framework. |
||||||
|
|
||||||
* Разрабока ведется в отдельном брэнче |
Изменения никак не трогают старый функционал. |
||||||
* После комита изменений можно проверить свою работу по следующему адресу: .lms.test.spicycms.com |
|
||||||
* После проверки тестового сайта по имени брэнча, брэнч помечается к мерж реквесту |
|
||||||
* Ответсвенный инженер производит код ревью и запускает/отклоняет мерж |
|
||||||
* Если сайт запустился на демо сайте, код в ручом режиме можно обновить на продакшен сервере |
|
||||||
|
|
||||||
**Замечания** |
Имеет смысл пробежаться по middl |
||||||
|
|
||||||
* Мерж реквест лучше производить в ветку develop(чтобы исключить случайного обновления кода на демо сайте) |
|
||||||
* Внимание! Разработчик обязан проверить работоспособность тестового сайта по имени созданного брэнча .lms.test.spicycms.com |
|
||||||
* Если необходимы тестовые данные разработчик их подготавливает дополнительно |
|
||||||
* Если нет возможности добавить тестовые данные в авто режиме, разработчик добавляет инструкцию в README файл по запуску необходимых команд |
|
||||||
(Под тестовыми данными подразумеваются фикстуры) |
|
||||||
|
|||||||
@ -0,0 +1,21 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.utils.timezone |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('access', '0089_auto_20170810_0904'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='user', |
||||||
|
name='delay_date', |
||||||
|
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True, verbose_name='Задержка до. Не включая этот день.'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
from django.conf.urls import url |
||||||
|
from access import new_view as views |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
url(r'teachers/$', views.TeacherListView.as_view()), |
||||||
|
url(r'info/$', views.InfoUserView.as_view()), |
||||||
|
url(r'check/$', views.CheckUserView.as_view()), |
||||||
|
url(r'registration/$', views.RegistrationView.as_view()), |
||||||
|
url(r'change_password/$', views.ChangePasswordView.as_view()), |
||||||
|
url(r'login/$', views.LoginView.as_view()), |
||||||
|
url(r'logout/$', views.LogoutView.as_view()), |
||||||
|
] |
||||||
@ -0,0 +1,100 @@ |
|||||||
|
from django.contrib.auth import get_user_model |
||||||
|
from django.contrib import auth |
||||||
|
from rest_framework.views import APIView |
||||||
|
from rest_framework.renderers import JSONRenderer |
||||||
|
from rest_framework.response import Response |
||||||
|
|
||||||
|
from access.serializers import UserInitSerializer |
||||||
|
from courses.models import Course |
||||||
|
|
||||||
|
|
||||||
|
class TeacherListView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
status_code = 200 |
||||||
|
|
||||||
|
def get(self, request): |
||||||
|
kwargs = dict( |
||||||
|
in_role='T', |
||||||
|
is_active=True, |
||||||
|
reg_status=4, |
||||||
|
) |
||||||
|
res = [] |
||||||
|
course_id = request.GET.get('course_id', 0) |
||||||
|
if course_id: |
||||||
|
kwargs['course_teachers'] = Course.objects.get(id=course_id) |
||||||
|
for teacher in get_user_model().objects.filter(**kwargs): |
||||||
|
res.append(teacher.full_name()) |
||||||
|
return Response(res, self.status_code) |
||||||
|
|
||||||
|
|
||||||
|
class CheckUserView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
status_code = 200 |
||||||
|
|
||||||
|
def get(self, request): |
||||||
|
if request.user.is_authenticated() and (request.user.in_role in ['M', 'S', 'S2', 'A'] or request.user.is_admin): |
||||||
|
return Response(True, status=self.status_code) |
||||||
|
return Response(False, status=self.status_code) |
||||||
|
|
||||||
|
|
||||||
|
class InfoUserView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
status_code = 200 |
||||||
|
|
||||||
|
def get(self, request): |
||||||
|
if request.user.is_authenticated(): |
||||||
|
return Response(UserInitSerializer(request.user).data, status=self.status_code) |
||||||
|
return Response('anonymous', status=self.status_code) |
||||||
|
|
||||||
|
|
||||||
|
class RegistrationView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def post(request): |
||||||
|
try: |
||||||
|
user = get_user_model().objects.get(email=request.JSON['email'].lower()) |
||||||
|
except get_user_model().DoesNotExist: |
||||||
|
user = get_user_model().objects.create_user( |
||||||
|
email=request.JSON['email'].lower(), |
||||||
|
) |
||||||
|
user.set_password(request.JSON['password']) |
||||||
|
user.reg_status = '2' |
||||||
|
user.save() |
||||||
|
return Response(UserInitSerializer(user).data, status=200) |
||||||
|
|
||||||
|
|
||||||
|
class ChangePasswordView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def post(request): |
||||||
|
if request.user.is_authenticated and not request.user.check_password(request.JSON['old_password']): |
||||||
|
return Response("Неверный пароль", status=404) |
||||||
|
request.user.set_password(request.JSON['new_password']) |
||||||
|
request.user.save() |
||||||
|
return Response("Пароль был изменён", status=200) |
||||||
|
|
||||||
|
|
||||||
|
class LoginView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def post(request): |
||||||
|
if not request.user.is_authenticated(): |
||||||
|
user = auth.authenticate(email=request.JSON.get('email'), password=request.JSON.get('password')) |
||||||
|
try: |
||||||
|
auth.login(request, user) |
||||||
|
except AttributeError: |
||||||
|
return Response("Неверный пароль", status=404) |
||||||
|
return Response(UserInitSerializer(request.user).data, status=200) |
||||||
|
|
||||||
|
|
||||||
|
class LogoutView(APIView): |
||||||
|
renderer_classes = (JSONRenderer,) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def post(request): |
||||||
|
if request.user.is_authenticated(): |
||||||
|
auth.logout(request) |
||||||
|
return Response(status=204) |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
from django.contrib.auth import get_user_model |
||||||
|
from rest_framework import serializers |
||||||
|
|
||||||
|
|
||||||
|
class UserInitSerializer(serializers.ModelSerializer): |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = get_user_model() |
||||||
|
fields = ['id', 'email', 'phone', 'name', |
||||||
|
'fname', 'oname', 'city', 'b_day'] |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
from django.conf.urls import url, include |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
url(r'courses/', include('courses.new_urls')), |
||||||
|
url(r'users/', include('access.new_urls')), |
||||||
|
] |
||||||
@ -1,22 +0,0 @@ |
|||||||
# -*- coding: utf-8 -*- |
|
||||||
# Generated by Django 1.9.3 on 2017-08-10 09:04 |
|
||||||
from __future__ import unicode_literals |
|
||||||
|
|
||||||
import datetime |
|
||||||
from django.db import migrations, models |
|
||||||
import django.db.models.deletion |
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration): |
|
||||||
|
|
||||||
dependencies = [ |
|
||||||
('courses', '0044_auto_20170621_1548'), |
|
||||||
] |
|
||||||
|
|
||||||
operations = [ |
|
||||||
migrations.AlterField( |
|
||||||
model_name='lesson', |
|
||||||
name='on_comment', |
|
||||||
field=models.CharField(choices=[('N', 'Включены'), ('F', 'Отключены'), ('T', 'Подчиняется теме')], default='T', help_text='https://go.skillbox.ru/management/faq/37', max_length=1, verbose_name='Блок комментариев'), |
|
||||||
), |
|
||||||
] |
|
||||||
@ -0,0 +1,53 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
import datetime |
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('courses', '0044_auto_20170621_1548'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='course', |
||||||
|
name='mentors', |
||||||
|
field=models.ManyToManyField(blank=True, related_name='course_mentors', to=settings.AUTH_USER_MODEL, verbose_name='Кураторы'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='diploma', |
||||||
|
name='date_size', |
||||||
|
field=models.IntegerField(null=True, verbose_name='Размер даты'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='diploma', |
||||||
|
name='key', |
||||||
|
field=models.IntegerField(verbose_name='Последний ключ'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='diploma', |
||||||
|
name='key_size', |
||||||
|
field=models.IntegerField(null=True, verbose_name='Размер ключа'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='diploma', |
||||||
|
name='name_size', |
||||||
|
field=models.IntegerField(null=True, verbose_name='Размер имени'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='lesson', |
||||||
|
name='on_comment', |
||||||
|
field=models.CharField(choices=[('N', 'Включены'), ('F', 'Отключены'), ('T', 'Подчиняется теме')], default='T', help_text='https://go.skillbox.ru/management/faq/37', max_length=1, verbose_name='Блок комментариев'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='materialdirection', |
||||||
|
name='mentors', |
||||||
|
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Кураторы'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
from django.conf.urls import url |
||||||
|
from courses import new_view as views |
||||||
|
|
||||||
|
urlpatterns = [ |
||||||
|
url(r'theme/detail/([0-9]{1,99})/$', views.ThemeDetailView.as_view()), |
||||||
|
url(r'lesson/detail/([0-9]{1,99})/$', views.LessonDetailView.as_view()), |
||||||
|
url(r'detail/([0-9]{1,99})/$', views.CourseDetailView.as_view()), |
||||||
|
url(r'tree/([0-9]{1,99})/$', views.TreeView.as_view()), |
||||||
|
url(r'directions/$', views.DirectionListView.as_view()), |
||||||
|
url(r'^$', views.CourseListView.as_view()), |
||||||
|
] |
||||||
@ -0,0 +1,159 @@ |
|||||||
|
from rest_framework import serializers |
||||||
|
import json |
||||||
|
# from django.contrib.auth import get_user_model |
||||||
|
# from django.core.exceptions import ObjectDoesNotExist |
||||||
|
|
||||||
|
from courses.models import Course, CourseTheme, Lesson, Homework, Exam |
||||||
|
|
||||||
|
|
||||||
|
class LessonSerializer(serializers.ModelSerializer): |
||||||
|
on_comment = serializers.SerializerMethodField() |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Lesson |
||||||
|
fields = ( |
||||||
|
'id', 'title', 'on_comment', 'materials', |
||||||
|
'free', 'video', 'video_id', |
||||||
|
) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_on_comment(self): |
||||||
|
return self.on_comment == 'N' or self.on_comment == 'T' and self.theme.on_comment |
||||||
|
|
||||||
|
|
||||||
|
class ThemeSerializer(serializers.ModelSerializer): |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = CourseTheme |
||||||
|
exclude = ('price_type', '_type', 'sort', 'on_comment') |
||||||
|
|
||||||
|
|
||||||
|
class CourseListSerializer(serializers.ModelSerializer): |
||||||
|
length = serializers.SerializerMethodField() |
||||||
|
level = serializers.SerializerMethodField() |
||||||
|
direction = serializers.SerializerMethodField() |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Course |
||||||
|
fields = ['id', 'title', 'length', |
||||||
|
'level', 'direction', 'image',] |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_length(self): |
||||||
|
summary = 0 |
||||||
|
for theme_slim in json.loads(self.normalmap.json_tree): |
||||||
|
for simple_object in theme_slim['body']: |
||||||
|
if simple_object.split('_')[1] == 'L': |
||||||
|
summary += 1 |
||||||
|
return summary |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_level(self): |
||||||
|
return self.get_level_display() |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_direction(self): |
||||||
|
return self.direction.title |
||||||
|
|
||||||
|
|
||||||
|
class CourseTreeSerializer(serializers.ModelSerializer): |
||||||
|
children = serializers.SerializerMethodField() |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Course |
||||||
|
fields = ['id', 'title', 'children'] |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_children(self): |
||||||
|
theme_list = json.loads(self.normalmap.json_tree) |
||||||
|
map = [] |
||||||
|
for theme_slim in theme_list: |
||||||
|
theme = CourseTheme.objects.get(id=theme_slim['id']) |
||||||
|
theme_obj = { |
||||||
|
'id': theme.id, |
||||||
|
'title': theme.title, |
||||||
|
'lessons': [], |
||||||
|
'tasks': [], |
||||||
|
} |
||||||
|
for simple_object in theme_slim['body']: |
||||||
|
val = simple_object.split('_')[0] |
||||||
|
if simple_object.split('_')[1] == 'L': |
||||||
|
lesson = Lesson.objects.get(id=val) |
||||||
|
lesson_obj = {'id': lesson.id, 'title': lesson.title} |
||||||
|
theme_obj['lessons'].append(lesson_obj) |
||||||
|
|
||||||
|
if simple_object.split('_')[1] == 'H': |
||||||
|
task = Homework.objects.get(id=val) |
||||||
|
task_obj = { |
||||||
|
'id': task.id, |
||||||
|
'is_exam': False, |
||||||
|
} |
||||||
|
theme_obj['tasks'].append(task_obj) |
||||||
|
|
||||||
|
if simple_object.split('_')[1] == 'E': |
||||||
|
task = Exam.objects.get(id=val) |
||||||
|
task_obj = { |
||||||
|
'id': task.id, |
||||||
|
'is_exam': True, |
||||||
|
} |
||||||
|
theme_obj['tasks'].append(task_obj) |
||||||
|
|
||||||
|
map.append(theme_obj) |
||||||
|
|
||||||
|
return map |
||||||
|
|
||||||
|
|
||||||
|
class CourseDetailSerializer(serializers.ModelSerializer): |
||||||
|
level = serializers.SerializerMethodField() |
||||||
|
direction = serializers.SerializerMethodField() |
||||||
|
teachers = serializers.SerializerMethodField() |
||||||
|
|
||||||
|
class Meta: |
||||||
|
model = Course |
||||||
|
exclude = ( |
||||||
|
'slug', 'mentors', 'page', 'sort', |
||||||
|
'preview', 'use_fail', 'basic_len', |
||||||
|
'addition_len', 'min_price', 'buy_icon', |
||||||
|
'must_build', 'keywords', 'recommend', |
||||||
|
) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_level(self): |
||||||
|
return self.get_level_display() |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_direction(self): |
||||||
|
return self.direction.title |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def get_teachers(self): |
||||||
|
return [teacher.full_name() for teacher in self.teachers.all()] |
||||||
|
|
||||||
|
|
||||||
|
# class UserSerializer(serializers.ModelSerializer): |
||||||
|
# statistics = serializers.SerializerMethodField('get_statistic') |
||||||
|
# games = serializers.SerializerMethodField('get_my_games') |
||||||
|
# is_anonymous = serializers.BooleanField() |
||||||
|
# |
||||||
|
# @staticmethod |
||||||
|
# def get_my_games(self): |
||||||
|
# res = {} |
||||||
|
# try: |
||||||
|
# res['active'] = GameSerializer(self.game_set.get(state__lte=1)).data |
||||||
|
# except ObjectDoesNotExist: |
||||||
|
# res['active'] = {} |
||||||
|
# |
||||||
|
# res['archive'] = [GameSerializer(i).data for i in self.game_set.all().filter(state=2)] |
||||||
|
# return res |
||||||
|
# |
||||||
|
# @staticmethod |
||||||
|
# def get_statistic(self): |
||||||
|
# try: |
||||||
|
# statistics = StatisticSerializer(Statistic.objects.get(user=self)).data |
||||||
|
# except ObjectDoesNotExist: |
||||||
|
# statistics = {} |
||||||
|
# return statistics |
||||||
|
# |
||||||
|
# class Meta: |
||||||
|
# model = get_user_model() |
||||||
|
# fields = ['id', 'username', 'email', 'is_active', 'statistics', 'games', 'is_anonymous'] |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
import os, sys |
||||||
|
import django, json |
||||||
|
|
||||||
|
sys.path.append("../") |
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") |
||||||
|
django.setup() |
||||||
|
|
||||||
|
from courses.models import Course, NormalMap, CourseTheme, Lesson, Homework, Exam |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
for course in Course.objects.all(): |
||||||
|
tree = [] |
||||||
|
for theme in CourseTheme.objects.filter(course=course).order_by('sort'): |
||||||
|
tree.append({'id': theme.id, 'body': |
||||||
|
[str(i.id) + "_L" for i in Lesson.objects.filter(theme=theme).order_by('sort')] + |
||||||
|
[str(i.id) + "_H" for i in Homework.objects.filter(theme=theme).order_by('sort')] + |
||||||
|
[str(i.id) + "_E" for i in Exam.objects.filter(theme=theme).order_by('sort')] |
||||||
|
}) |
||||||
|
|
||||||
|
obj, _is_create = NormalMap.objects.get_or_create(course=course) |
||||||
|
obj.json_tree = json.dumps(tree) |
||||||
|
obj.save() |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
import django.db.models.deletion |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('courses', '0045_auto_20170918_0811'), |
||||||
|
('finance', '0070_auto_20170424_1638'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='bill', |
||||||
|
name='create_letters', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, related_name='bill_create_letter', to='service.MailBox', verbose_name='Письма при создании'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='bill', |
||||||
|
name='finish_letters', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, related_name='bill_finish_letter', to='service.MailBox', verbose_name='Письма завершения'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='installment', |
||||||
|
name='payments', |
||||||
|
field=models.ManyToManyField(blank=True, related_name='bill_point', to='finance.Bill', verbose_name='Платежи'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='price', |
||||||
|
name='included', |
||||||
|
field=models.ManyToManyField(blank=True, help_text='Если задействовать эту функцию, стандартная схема подписок будет не активна', to='courses.CourseMap', verbose_name='Включены'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='requestalert', |
||||||
|
name='requests', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, to='finance.ServiceRequest', verbose_name='Количество заявок'), |
||||||
|
), |
||||||
|
] |
||||||
@ -1,22 +0,0 @@ |
|||||||
# -*- coding: utf-8 -*- |
|
||||||
# Generated by Django 1.9.3 on 2017-08-10 09:04 |
|
||||||
from __future__ import unicode_literals |
|
||||||
|
|
||||||
from django.db import migrations, models |
|
||||||
import django.db.models.deletion |
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration): |
|
||||||
|
|
||||||
dependencies = [ |
|
||||||
('courses', '0045_auto_20170810_0904'), |
|
||||||
('finance', '0070_auto_20170424_1638'), |
|
||||||
] |
|
||||||
|
|
||||||
operations = [ |
|
||||||
migrations.AddField( |
|
||||||
model_name='bill', |
|
||||||
name='flow', |
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Flow', verbose_name='Поток'), |
|
||||||
), |
|
||||||
] |
|
||||||
@ -0,0 +1,25 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('journals', '0072_auto_20170810_0904'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='diplomaj', |
||||||
|
name='key', |
||||||
|
field=models.IntegerField(blank=True, null=True, verbose_name='Ключ'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='teacherj', |
||||||
|
name='waiting', |
||||||
|
field=models.ManyToManyField(blank=True, related_name='map_waiting', to='courses.CourseMap', verbose_name='Доп изучения'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('library', '0022_auto_20161101_1321'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='article', |
||||||
|
name='comments', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, to='management.Comment', verbose_name='Комментарии'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='article', |
||||||
|
name='favorite', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, related_name='article_as_favorites', to=settings.AUTH_USER_MODEL, verbose_name='В фаворитах'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='article', |
||||||
|
name='likes', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, max_length=255, related_name='acticle_likes', to=settings.AUTH_USER_MODEL, verbose_name='Лайки'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='article', |
||||||
|
name='tags', |
||||||
|
field=models.ManyToManyField(blank=True, to='library.Tags', verbose_name='Теги'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('management', '0090_auto_20161230_1643'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='comment', |
||||||
|
name='answers', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, related_name='_comment_answers_+', to='management.Comment', verbose_name='Форумные ответы'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='comment', |
||||||
|
name='replies', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, related_name='_comment_replies_+', to='management.Comment', verbose_name='Ответы'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='faq', |
||||||
|
name='comments', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, to='management.Comment', verbose_name='Комментарии'), |
||||||
|
), |
||||||
|
] |
||||||
Binary file not shown.
@ -0,0 +1,31 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# Generated by Django 1.9.3 on 2017-09-18 08:11 |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('practice', '0020_workshop_body'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='datasheet', |
||||||
|
name='users', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, to=settings.AUTH_USER_MODEL, verbose_name='Пользователи'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='workshop', |
||||||
|
name='tools', |
||||||
|
field=models.ManyToManyField(blank=True, to='practice.WorkshopTools', verbose_name='Используемые инструменты'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='workshop', |
||||||
|
name='users', |
||||||
|
field=models.ManyToManyField(blank=True, editable=False, to=settings.AUTH_USER_MODEL, verbose_name='Пользователи'), |
||||||
|
), |
||||||
|
] |
||||||
Loading…
Reference in new issue