commit
6255658dd5
65 changed files with 1249 additions and 195 deletions
@ -0,0 +1,18 @@ |
||||
from django.contrib.auth import login |
||||
from django.utils.deprecation import MiddlewareMixin |
||||
|
||||
from rest_framework.authtoken.models import Token |
||||
|
||||
|
||||
class TokenAuthLoginMiddleware(MiddlewareMixin): |
||||
|
||||
def process_request(self, request): |
||||
if 'token' in request.GET: |
||||
token = request.GET.get('token') |
||||
if token: |
||||
try: |
||||
token = Token.objects.get(key=token) |
||||
user = token.user |
||||
login(request, user) |
||||
except Token.DoesNotExist: |
||||
pass |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-16 11:05 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('content', '0014_auto_20180215_1503'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='content', |
||||
name='uuid', |
||||
field=models.UUIDField(blank=True, null=True), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.2 on 2018-03-12 10:05 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('course', '0034_auto_20180215_1503'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='comment', |
||||
name='deactivated_at', |
||||
field=models.DateTimeField(blank=True, default=None, null=True), |
||||
), |
||||
] |
||||
@ -1,5 +1,10 @@ |
||||
{% load mptt_tags %} |
||||
|
||||
{% recursetree object.comments.all %} |
||||
{% if not node.deactivated_at %} |
||||
{% include './comment.html' %} |
||||
{{ children }} {% endrecursetree %} |
||||
{% if not node.is_leaf_node %} |
||||
{{ children }} |
||||
{% endif %} |
||||
{% endif %} |
||||
{% endrecursetree %} |
||||
|
||||
@ -1,19 +1,28 @@ |
||||
{% load thumbnail %} |
||||
{% if results %} |
||||
<div class="title">Галерея итогов обучения</div> |
||||
<div class="examples"> |
||||
<div class="examples gallery"> |
||||
{% for image in course.gallery.gallery_images.all %} |
||||
<div class="examples__item"> |
||||
<img class="examples__pic" src="{{ image.img.image.url }}"> |
||||
<a href="{{ image.img.image.url }}"> |
||||
{% thumbnail image.img.image "140x140" crop="center" as im %} |
||||
<img class="examples__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"> |
||||
{% endthumbnail %} |
||||
</a> |
||||
</div> |
||||
{% endfor %} |
||||
</div> |
||||
{% else %} |
||||
<div class="content-block title">{{ content.title }}</div> |
||||
<div class="examples"> |
||||
<div class="examples gallery"> |
||||
{% for image in content.gallery_images.all %} |
||||
<div class="examples__item"> |
||||
<img class="examples__pic" src="{{ image.img.image.url }}"> |
||||
<a href="{{ image.img.image.url }}"> |
||||
{% thumbnail image.img.image "140x140" crop="center" as im %} |
||||
<img class="examples__pic" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}"> |
||||
{% endthumbnail %} |
||||
</a> |
||||
</div> |
||||
{% endfor %} |
||||
</div> |
||||
{% endif %} |
||||
{% endif %} |
||||
|
||||
@ -1,6 +1,8 @@ |
||||
<div class="content-block title"> |
||||
{{ content.title }} |
||||
</div> |
||||
<div> |
||||
<img class="content-block pic" src="{{ content.img.image.url }}" alt=""> |
||||
</div> |
||||
<div class="gallery"> |
||||
<a href="{{ content.img.image.url }}"> |
||||
<img class="content-block pic" src="{{ content.img.image.url }}" alt=""> |
||||
</a> |
||||
</div> |
||||
|
||||
@ -0,0 +1,13 @@ |
||||
{% extends "notification/email/_base.html" %} |
||||
|
||||
{% block content %} |
||||
<p style="margin: 0 0 20px">Поздравляем! Вам одобрено назначение преподавателем!</p> |
||||
<div style="margin-bottom: 10px;"> |
||||
<p>Теперь вы можете публиковать курсы.</p> |
||||
{% if password and email %} |
||||
<p><strong>Параметры входа:</strong></p> |
||||
<p><strong>email:</strong> {{ email }}</p> |
||||
<p><strong>пароль:</strong> {{ password }}</p> |
||||
{% endif %} |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,8 @@ |
||||
{% extends "notification/email/_base.html" %} |
||||
|
||||
{% block content %} |
||||
<p style="margin: 0 0 20px">К сожалению вам отказано в назначении преподавателем!</p> |
||||
<div style="margin-bottom: 10px;"> |
||||
<p>{{ cause }}</p> |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,18 @@ |
||||
from mixpanel import Mixpanel |
||||
|
||||
from django.conf import settings |
||||
|
||||
from project.celery import app |
||||
|
||||
|
||||
@app.task |
||||
def transaction_to_mixpanel(user_id, amount, time, product_type): |
||||
mix = Mixpanel(settings.MIX_TOKEN) |
||||
mix.people_track_charge( |
||||
user_id, |
||||
amount, |
||||
{ |
||||
'$time': time, |
||||
'product_type': product_type, |
||||
} |
||||
) |
||||
@ -0,0 +1,12 @@ |
||||
{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} |
||||
<div class="section"> |
||||
<div class="section__center center center_xs"> |
||||
<div class="done"> |
||||
<div class="done__title title">Вы успешно приобрели курс!</div> |
||||
<div class="done__foot"> |
||||
<a class="done__btn btn btn_md btn_stroke" href="{% url 'course' course.id %}">ПЕРЕЙТИ К КУРСУ</a> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,58 @@ |
||||
[ |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 1, |
||||
"fields": { |
||||
"title": "Новости школы", |
||||
"auto_add": false |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 2, |
||||
"fields": { |
||||
"title": "Новые курсы", |
||||
"auto_add": true |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 3, |
||||
"fields": { |
||||
"title": "Бонусы от партнёров", |
||||
"auto_add": false |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 4, |
||||
"fields": { |
||||
"title": "Акции", |
||||
"auto_add": true |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 5, |
||||
"fields": { |
||||
"title": "Партнёрские акции", |
||||
"auto_add": false |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 6, |
||||
"fields": { |
||||
"title": "Новости компании", |
||||
"auto_add": true |
||||
} |
||||
}, |
||||
{ |
||||
"model": "user.subscriptioncategory", |
||||
"pk": 7, |
||||
"fields": { |
||||
"title": "Комментарии в которых участвуете", |
||||
"auto_add": false |
||||
} |
||||
} |
||||
] |
||||
@ -0,0 +1,27 @@ |
||||
# Generated by Django 2.0.2 on 2018-03-12 14:01 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0008_auto_20180212_0750'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='AuthorRequest', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('first_name', models.CharField(max_length=30, verbose_name='first name')), |
||||
('last_name', models.CharField(max_length=150, verbose_name='last name')), |
||||
('email', models.EmailField(max_length=254, verbose_name='email address')), |
||||
('about', models.CharField(blank=True, max_length=1000, null=True, verbose_name='О себе')), |
||||
('facebook', models.URLField(blank=True, default='', null=True)), |
||||
('status', models.PositiveSmallIntegerField(choices=[(0, 'pending'), (1, 'accepted'), (2, 'declined')], default=0)), |
||||
('created_at', models.DateTimeField(auto_now_add=True)), |
||||
('update_at', models.DateTimeField(auto_now=True)), |
||||
], |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.2 on 2018-03-12 16:10 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0009_authorrequest'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='authorrequest', |
||||
name='email', |
||||
field=models.EmailField(max_length=254, unique=True, verbose_name='email address'), |
||||
), |
||||
] |
||||
@ -0,0 +1,17 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-13 07:44 |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0010_auto_20180312_1610'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterModelOptions( |
||||
name='authorrequest', |
||||
options={'ordering': ('-created_at',), 'verbose_name': 'Заявка не преподавателя', 'verbose_name_plural': 'Заявки не преподавателя'}, |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-13 07:49 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0011_auto_20180313_0744'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='authorrequest', |
||||
name='cause', |
||||
field=models.TextField(blank=True, null=True, verbose_name='Причина отказа'), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-13 10:10 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0012_authorrequest_cause'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='authorrequest', |
||||
name='declined_send_at', |
||||
field=models.DateTimeField(blank=True, null=True), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-13 10:55 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0013_authorrequest_declined_send_at'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='authorrequest', |
||||
name='accepted_send_at', |
||||
field=models.DateTimeField(blank=True, null=True), |
||||
), |
||||
] |
||||
@ -0,0 +1,45 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-15 05:47 |
||||
|
||||
from django.conf import settings |
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0014_authorrequest_accepted_send_at'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='EmailSubscription', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), |
||||
('mailchimp_status', models.PositiveSmallIntegerField(choices=[(0, 'error'), (1, 'sent')], default=0)), |
||||
], |
||||
), |
||||
migrations.CreateModel( |
||||
name='SubscriptionCategory', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('title', models.CharField(max_length=100)), |
||||
], |
||||
options={ |
||||
'verbose_name': 'Категория подписки', |
||||
'verbose_name_plural': 'Категории подписки', |
||||
'ordering': ('title',), |
||||
}, |
||||
), |
||||
migrations.AddField( |
||||
model_name='emailsubscription', |
||||
name='categories', |
||||
field=models.ManyToManyField(to='user.SubscriptionCategory'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='emailsubscription', |
||||
name='user', |
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), |
||||
), |
||||
] |
||||
@ -0,0 +1,20 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-15 06:03 |
||||
|
||||
from django.conf import settings |
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0015_auto_20180315_0547'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='emailsubscription', |
||||
name='user', |
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='email_subscription', to=settings.AUTH_USER_MODEL), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-15 06:18 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0016_auto_20180315_0603'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='subscriptioncategory', |
||||
name='auto_add', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
] |
||||
@ -0,0 +1,19 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-15 17:19 |
||||
|
||||
from django.db import migrations |
||||
import phonenumber_field.modelfields |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0017_subscriptioncategory_auto_add'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='user', |
||||
name='phone', |
||||
field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, unique=True), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 2.0.3 on 2018-03-20 08:40 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('user', '0018_user_phone'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='user', |
||||
name='show_in_mainpage', |
||||
field=models.BooleanField(default=False, verbose_name='Показывать на главной странице'), |
||||
), |
||||
] |
||||
@ -0,0 +1,22 @@ |
||||
from mixpanel import Mixpanel |
||||
|
||||
from django.conf import settings |
||||
|
||||
from project.celery import app |
||||
|
||||
|
||||
@app.task |
||||
def user_to_mixpanel(user_id, email, phone, first_name, last_name, date_joined, role, subscriptions): |
||||
mix = Mixpanel(settings.MIX_TOKEN) |
||||
mix.people_set( |
||||
user_id, |
||||
{ |
||||
'$email': email, |
||||
'$phone': phone, |
||||
'$first_name': first_name, |
||||
'$last_name': last_name, |
||||
'$created': date_joined, |
||||
'role': role, |
||||
'subscriptions': subscriptions, |
||||
} |
||||
) |
||||
@ -0,0 +1,12 @@ |
||||
{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} |
||||
<div class="section"> |
||||
<div class="section__center center center_xs"> |
||||
<div class="done"> |
||||
<div class="done__title title">Ваша заявка отправлена!</div> |
||||
<div class="done__foot"> |
||||
<a class="done__btn btn btn_md btn_stroke" href="/">ПЕРЕЙТИ К ГЛАВНОЙ</a> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,69 @@ |
||||
{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} {% if messages %} |
||||
<div class="section section_menu"> |
||||
<div class="section__center center center_xs"> |
||||
{% for message in messages %} |
||||
<div class="message message_{{ message.tags }}">{{ message }}</div> |
||||
{% endfor %} |
||||
</div> |
||||
</div> |
||||
{% endif %} |
||||
<div class="section"> |
||||
<div class="section__center center center_xs"> |
||||
<form class="form" method="POST">{% csrf_token %} |
||||
<div class="form__group"> |
||||
<div class="form__title">Стать автором</div> |
||||
<div class="form__fieldset"> |
||||
<div class="form__field field{% if form.first_name.errors %} error{% endif %}"> |
||||
<div class="field__label">ИМЯ</div> |
||||
<div class="field__wrap"> |
||||
<input name='first_name' class="field__input" type="text" placeholder="Имя" value="{{ form.first_name.value }}"> |
||||
</div> |
||||
{% if form.first_name.errors %} |
||||
<div class="field__error">Укажите корректно свои данные</div> |
||||
{% endif %} |
||||
</div> |
||||
<div class="form__field field{% if form.last_name.errors %} error{% endif %}"> |
||||
<div class="field__label">ФАМИЛИЯ</div> |
||||
<div class="field__wrap"> |
||||
<input name='last_name' class="field__input" type="text" placeholder="Фамилия" value="{{ form.last_name.value }}"> |
||||
</div> |
||||
{% if form.last_name.errors %} |
||||
<div class="field__error">Укажите корректно свои данные</div> |
||||
{% endif %} |
||||
</div> |
||||
</div> |
||||
<div class="form__field field{% if form.email.errors %} error{% endif %}"> |
||||
<div class="field__label">Почта</div> |
||||
<div class="field__wrap"> |
||||
<input name='email' class="field__input" type="email" placeholder="Почта" value="{{ form.email.value }}"> |
||||
</div> |
||||
{% if form.email.errors %} |
||||
<div class="field__error">Укажите корректно свои данные</div> |
||||
{% endif %} |
||||
</div> |
||||
<div class="form__field field{% if form.about.errors %} error{% endif %}"> |
||||
<div class="field__label">О себе</div> |
||||
<div class="field__wrap"> |
||||
<textarea name='about' class="field__textarea" placeholder="Расскажите о себе и своем опыте">{% if form.about.value %}{{ form.about.value }}{% endif %}</textarea> |
||||
</div> |
||||
{% if form.about.errors %} |
||||
<div class="field__error">Укажите корректно свои данные</div> |
||||
{% endif %} |
||||
</div> |
||||
<div class="form__field field{% if form.facebook.errors %} error{% endif %}"> |
||||
<div class="field__label">FACEBOOK</div> |
||||
<div class="field__wrap"> |
||||
<input name='facebook' class="field__input" type="text" placeholder="https://facebook.com/lilcitycompany" value="{% if form.facebook.value %}{{ form.facebook.value }}{% endif %}"> |
||||
</div> |
||||
{% if form.facebook.errors %} |
||||
<div class="field__error">Укажите корректно свои данные</div> |
||||
{% endif %} |
||||
</div> |
||||
</div> |
||||
<div class="form__foot"> |
||||
<button class="form__btn btn btn_md">СОХРАНИТЬ</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,52 @@ |
||||
{% load static %} |
||||
<!DOCTYPE html> |
||||
<html lang="ru"> |
||||
|
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
||||
<link rel="stylesheet" media="all" href={% static "app.css" %}> |
||||
</head> |
||||
|
||||
<body> |
||||
<div class="section section_gray"> |
||||
<div class="section__center center center_md"> |
||||
<a id="schedule" name="schedule"> |
||||
<div class="title title_center">Расписание</div> |
||||
</a> |
||||
<div class="schedule"> |
||||
{% for school_schedule in school_schedules %} |
||||
<div class="schedule__item"> |
||||
<div class="schedule__day">{{ school_schedule }}</div> |
||||
<div class="schedule__wrap"> |
||||
<div class="schedule__title">{{ school_schedule.title }}</div> |
||||
<div class="schedule__content">{{ school_schedule.description }}</div> |
||||
<div class="schedule__toggle toggle"> |
||||
<button class="toggle__head js-toggle-head active">Материалы |
||||
<svg class="icon icon-arrow-down"> |
||||
<use xlink:href="{% static 'img/sprite.svg' %}#icon-arrow-down"></use> |
||||
</svg> |
||||
</button> |
||||
<div class="toggle__body">{{ school_schedule.materials }}</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
{% endfor %} |
||||
</div> |
||||
{% comment %} <div class="text text_mb0"> |
||||
<a href='#'>Распечатать расписание</a> чтобы не забыть |
||||
</div> {% endcomment %} |
||||
</div> |
||||
</div> |
||||
<script type="text/javascript" src={% static "app.js" %}></script> |
||||
<script type="text/javascript"> |
||||
var toggle__body = Array.from(document.getElementsByClassName("toggle__body")); |
||||
toggle__body.forEach(function (item, i, toggle__body) { |
||||
item.style.display = "block" |
||||
}); |
||||
window.print(); |
||||
window.close(); |
||||
</script> |
||||
</body> |
||||
</html> |
||||
@ -1,24 +1,28 @@ |
||||
# Python-3.6 |
||||
gunicorn==19.7.1 |
||||
requests==2.18.4 |
||||
Django==2.0.2 |
||||
django-anymail[mailgun]==1.2 |
||||
# paymentwall-python==1.0.7 |
||||
git+https://github.com/ivlevdenis/paymentwall-python.git |
||||
twilio==6.10.0 |
||||
psycopg2==2.7.3.2 |
||||
facepy==1.0.9 |
||||
Pillow==5.0.0 |
||||
django-active-link==0.1.2 |
||||
arrow==0.12.1 |
||||
celery[redis]==4.1.0 |
||||
Django==2.0.3 |
||||
django-active-link==0.1.2 |
||||
django-anymail[mailgun]==2.0 |
||||
django-cors-headers==2.2.0 |
||||
django-constance[database]==2.1.0 |
||||
django-filter==2.0.0.dev1 |
||||
django-mptt==0.9.0 |
||||
django-silk==2.0.0 |
||||
django-phonenumber-field==2.0.0 |
||||
django-polymorphic-tree==1.5 |
||||
celery[redis]==4.1.0 |
||||
djangorestframework==3.7.7 |
||||
drf-yasg[validation]==1.4.0 |
||||
django-silk==2.0.0 |
||||
django-cors-headers==2.1.0 |
||||
django-constance[database]==2.1.0 |
||||
drf-yasg[validation]==1.5.0 |
||||
facepy==1.0.9 |
||||
gunicorn==19.7.1 |
||||
mixpanel==4.3.2 |
||||
psycopg2-binary==2.7.4 |
||||
Pillow==5.0.0 |
||||
raven==6.6.0 |
||||
requests==2.18.4 |
||||
sorl-thumbnail==12.4.1 |
||||
twilio==6.10.5 |
||||
# paymentwall-python==1.0.7 |
||||
git+https://github.com/ivlevdenis/paymentwall-python.git |
||||
# python-instagram==1.3.2 |
||||
git+https://github.com/ivlevdenis/python-instagram.git |
||||
|
||||
Loading…
Reference in new issue