Merge branch 'develop' of https://gitlab.informatics.ru/2020-2021/online/s101/group-02/access_controller into develop
This commit is contained in:
commit
fb75d10642
@ -47,6 +47,9 @@ pip install -r requirements.txt
|
|||||||
./manage.py shell -c "from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser('vasya', '1@abc.net', 'promprog')"
|
./manage.py shell -c "from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser('vasya', '1@abc.net', 'promprog')"
|
||||||
./manage.py runserver
|
./manage.py runserver
|
||||||
```
|
```
|
||||||
|
Создать токен
|
||||||
|
|
||||||
|
Указать почту и токен в окружении
|
||||||
|
|
||||||
## Read more
|
## Read more
|
||||||
- Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au)
|
- Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au)
|
||||||
|
@ -15,7 +15,6 @@ from pathlib import Path
|
|||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ DEBUG = True
|
|||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
@ -37,6 +35,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'django_registration',
|
||||||
'main',
|
'main',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -72,7 +71,6 @@ TEMPLATES = [
|
|||||||
|
|
||||||
WSGI_APPLICATION = 'access_controller.wsgi.application'
|
WSGI_APPLICATION = 'access_controller.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
||||||
|
|
||||||
@ -83,7 +81,6 @@ DATABASES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
@ -102,7 +99,6 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
||||||
|
|
||||||
@ -116,7 +112,6 @@ USE_L10N = True
|
|||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
||||||
|
|
||||||
@ -127,3 +122,7 @@ STATICFILES_DIRS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
MEDIA_ROOT = BASE_DIR / 'media'
|
MEDIA_ROOT = BASE_DIR / 'media'
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
LOGIN_REDIRECT_URL = '/'
|
||||||
|
LOGOUT_REDIRECT_URL = '/'
|
||||||
|
|
||||||
|
@ -13,12 +13,23 @@ Including another URLconf
|
|||||||
1. Import the include() function: from django.urls import include, path
|
1. Import the include() function: from django.urls import include, path
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
|
from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
|
||||||
|
|
||||||
from main.views import main_page
|
from django.urls import path, include
|
||||||
|
from django.contrib.auth.views import LoginView
|
||||||
|
from django.urls import path, include
|
||||||
|
from access_controller import settings
|
||||||
|
from main.views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls, name='admin'),
|
||||||
path('', main_page),
|
path('', main_page),
|
||||||
|
path('register/', CustomRegistrationView.as_view(), name='registration'),
|
||||||
|
# path('', include('django_registration.backends.one_step.urls')),
|
||||||
|
path('profile/', profile_page, name='profile'),
|
||||||
|
path('accounts/login/', LoginView.as_view(extra_context={})), # TODO add extra context
|
||||||
|
path('accounts/', include('django.contrib.auth.urls'))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
9
docs/source/code.rst
Normal file
9
docs/source/code.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
*****
|
||||||
|
TODOs
|
||||||
|
*****
|
||||||
|
|
||||||
|
Extra Functions
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. automodule:: main.extra_func
|
||||||
|
:members:
|
@ -6,10 +6,13 @@
|
|||||||
Welcome to ZenDesk Access Controller's documentation!
|
Welcome to ZenDesk Access Controller's documentation!
|
||||||
=====================================================
|
=====================================================
|
||||||
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
|
code.rst
|
||||||
|
todo.rst
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
|
5
docs/source/todo.rst
Normal file
5
docs/source/todo.rst
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*****
|
||||||
|
TODOs
|
||||||
|
*****
|
||||||
|
|
||||||
|
.. todolist::
|
BIN
layouts/authorization/authorization.jpg
Normal file
BIN
layouts/authorization/authorization.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
104
main/extra_func.py
Normal file
104
main/extra_func.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from zenpy import Zenpy
|
||||||
|
from zenpy.lib.exception import APIException
|
||||||
|
|
||||||
|
from main.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
# Дополнительные функции
|
||||||
|
def set_and_get_name(user_profile: UserProfile):
|
||||||
|
"""
|
||||||
|
Функция устанавливает поле :class:`username` текущим именем в Zendesk
|
||||||
|
|
||||||
|
.. TODO::
|
||||||
|
Переделать с получением данных через API
|
||||||
|
|
||||||
|
:param UP: Объект профиля пользователя
|
||||||
|
:type UP: :class:`main.models.UserProfile`
|
||||||
|
:return: Имя пользователя
|
||||||
|
:rtype: :class:`str`
|
||||||
|
"""
|
||||||
|
return user_profile.user.username
|
||||||
|
|
||||||
|
|
||||||
|
def set_and_get_email(user_profile: UserProfile): # TODO: Переделать с получением данных через API
|
||||||
|
"""
|
||||||
|
Функция устанавливает поле :class:`user.email` текущей почтой в Zendesk
|
||||||
|
|
||||||
|
:param UP: Объект профиля пользователя
|
||||||
|
:type UP: :class:`main.models.UserProfile`
|
||||||
|
:return: Почта пользователя
|
||||||
|
:rtype: :class:`str`
|
||||||
|
"""
|
||||||
|
return user_profile.user.email
|
||||||
|
|
||||||
|
|
||||||
|
def set_and_get_role(user_profile: UserProfile): # TODO: Переделать с получением данных через API
|
||||||
|
"""
|
||||||
|
Функция устанавливает поле :class:`role` текущей ролью в Zendesk
|
||||||
|
|
||||||
|
:param UP: Объект профиля пользователя
|
||||||
|
:type UP: :class:`main.models.UserProfile`
|
||||||
|
:return: Роль пользователя
|
||||||
|
:rtype: :class:`str`
|
||||||
|
"""
|
||||||
|
return user_profile.role
|
||||||
|
|
||||||
|
|
||||||
|
def load_and_get_image(user_profile: UserProfile): # TODO: Переделать с получением изображения через API
|
||||||
|
"""
|
||||||
|
Функция загружает и устанавливает изображение в поле :class:`image`
|
||||||
|
|
||||||
|
:param UP: Объект профиля пользователя
|
||||||
|
:type UP: :class:`main.models.UserProfile`
|
||||||
|
:return: Название изображения
|
||||||
|
:rtype: :class:`str`
|
||||||
|
"""
|
||||||
|
return user_profile.image.name
|
||||||
|
|
||||||
|
|
||||||
|
def check_user_exist(email: str) -> bool:
|
||||||
|
"""
|
||||||
|
Функция проверяет, существует ли пользователь
|
||||||
|
|
||||||
|
:param email: Электронная почта пользователя
|
||||||
|
:type email: :class:`str`
|
||||||
|
:return: True, если существует, иначе False
|
||||||
|
:rtype: :class:`bool`
|
||||||
|
"""
|
||||||
|
admin_creds = {
|
||||||
|
'email': os.environ.get('Admin_email'),
|
||||||
|
'subdomain': 'ngenix1612197338',
|
||||||
|
'token': os.environ.get('Oauth_token'),
|
||||||
|
}
|
||||||
|
admin = Zenpy(**admin_creds)
|
||||||
|
zenpy_user = admin.search(email, type='user')
|
||||||
|
if zenpy_user:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_user_auth(email: str, password: str) -> bool:
|
||||||
|
"""
|
||||||
|
Функция проверяет, верны ли входные данные
|
||||||
|
|
||||||
|
:param email: Электроная почта пользователя
|
||||||
|
:type email: :class:`str`
|
||||||
|
:param password: Пароль пользователя
|
||||||
|
:type password: :class:`str`
|
||||||
|
:return: True, если входные данные верны, иначе False
|
||||||
|
:raise :class:`APIException`: исключение, вызываемое если пользователь не аутентифицирован
|
||||||
|
:rtype: :class:`bool`
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
creds = {
|
||||||
|
'email': email,
|
||||||
|
'subdomain': 'ngenix1612197338',
|
||||||
|
'password': password,
|
||||||
|
}
|
||||||
|
user = Zenpy(**creds)
|
||||||
|
user.search(email, type='user')
|
||||||
|
except APIException:
|
||||||
|
return False
|
||||||
|
return True
|
34
main/forms.py
Normal file
34
main/forms.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from django import forms
|
||||||
|
from django_registration.forms import RegistrationFormUniqueEmail
|
||||||
|
|
||||||
|
|
||||||
|
class CustomRegistrationForm(RegistrationFormUniqueEmail):
|
||||||
|
"""
|
||||||
|
Форма для регистрации :class:`django_registration.forms.RegistrationFormUniqueEmail`
|
||||||
|
с полем для ввода пароля от Zendesk аккаунта и с добавлением bootstrap-класса 'form-control' для всех полей
|
||||||
|
|
||||||
|
:param password_zen: Поле для ввода пароля от Zendesk
|
||||||
|
:type password_zen: :class:`django.forms.CharField`
|
||||||
|
"""
|
||||||
|
password_zen = forms.CharField(
|
||||||
|
required=True,
|
||||||
|
label="Пароль от Zendesk аккаунта",
|
||||||
|
strip=False,
|
||||||
|
widget=forms.PasswordInput(attrs={
|
||||||
|
'class': 'form-control'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
for visible in self.visible_fields():
|
||||||
|
if visible.field.widget.attrs.get('class', False):
|
||||||
|
print(visible.field.widget.attrs['class'].find('form-control'))
|
||||||
|
if visible.field.widget.attrs['class'].find('form-control') < 0:
|
||||||
|
visible.field.widget.attrs['class'] += 'form-control'
|
||||||
|
else:
|
||||||
|
visible.field.widget.attrs['class'] = 'form-control'
|
||||||
|
|
||||||
|
class Meta(RegistrationFormUniqueEmail.Meta):
|
||||||
|
fields = RegistrationFormUniqueEmail.Meta.fields
|
||||||
|
fields.insert(2, 'password_zen')
|
BIN
main/layout/base/base.png
Normal file
BIN
main/layout/base/base.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
18
main/migrations/0002_userprofile_name.py
Normal file
18
main/migrations/0002_userprofile_name.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.1.6 on 2021-02-08 16:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='userprofile',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(default='None', max_length=100),
|
||||||
|
),
|
||||||
|
]
|
@ -8,3 +8,4 @@ class UserProfile(models.Model):
|
|||||||
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
|
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
|
||||||
role = models.IntegerField()
|
role = models.IntegerField()
|
||||||
image = models.ImageField(upload_to='user_avatars')
|
image = models.ImageField(upload_to='user_avatars')
|
||||||
|
name = models.CharField(default='None', max_length=100)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
||||||
<html lang="ru" class="h-100">
|
<html lang="ru" class="h-100">
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<head>
|
<head>
|
||||||
@ -32,7 +33,7 @@
|
|||||||
|
|
||||||
<main class="flex-shrink-0">
|
<main class="flex-shrink-0">
|
||||||
<div class="container mt-4 mb-4">
|
<div class="container mt-4 mb-4">
|
||||||
<h1 class="mb-4">
|
<h1 class="mb-4 text-center">
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</h1>
|
</h1>
|
||||||
@ -52,5 +53,6 @@
|
|||||||
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
|
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
<a class="btn btn-secondary" href="">Выйти</a>
|
<a class="btn btn-secondary" href="/accounts/logout">Выйти</a>
|
||||||
<a class="btn btn-secondary" href="">Профиль</a>
|
<a class="btn btn-secondary" href="">Профиль</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
<a class="btn btn-secondary" href="">Войти</a>
|
<a class="btn btn-secondary" href="/accounts/login">Войти</a>
|
||||||
<a class="btn btn-secondary" href="">Зарегистрироваться</a>
|
<a class="btn btn-secondary" href="/accounts/register">Зарегистрироваться</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
15
main/templates/django_registration/registration_closed.html
Normal file
15
main/templates/django_registration/registration_closed.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends 'base/base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Регистрация завершена
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block heading %}
|
||||||
|
Регистрация
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<br>
|
||||||
|
<h4> Нет пользователя с указаным адресом электронной почты, либо был введён неверный пароль</h4>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,14 @@
|
|||||||
|
{% extends 'base/base.html' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Регистрация завершена
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block heading %}
|
||||||
|
Регистрация
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<br>
|
||||||
|
<h4> Регистрация прошла успешно. <a href="/login/">Войти сейчас</a></h4>
|
||||||
|
{% endblock %}
|
24
main/templates/django_registration/registration_form.html
Normal file
24
main/templates/django_registration/registration_form.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{% extends 'base/base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Регистрация
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block heading %}
|
||||||
|
Регистрация
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form method="post" action="">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
{{ field.label_tag }}
|
||||||
|
{{ field }}
|
||||||
|
<br>
|
||||||
|
{% if field.errors %}
|
||||||
|
<span>{{ field.errors }}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<input type="submit" value="Зарегистрироваться" class="clearfix">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
46
main/templates/pages/profile.html
Normal file
46
main/templates/pages/profile.html
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{% extends 'base/base.html' %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block title %}{{ pagename }}{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block heading %}Профиль{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<style>
|
||||||
|
.img{
|
||||||
|
width:auto;
|
||||||
|
height:auto;
|
||||||
|
max-width:150px!important;
|
||||||
|
max-height:500px!important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<br>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="container">
|
||||||
|
{% if image_name %}
|
||||||
|
<img src="/media/{{image_name}}" class="img img-thumbnail" alt="Аватар">
|
||||||
|
{% else %}
|
||||||
|
<img src="{% static 'no_avatar.png' %}" class="img img-thumbnail" alt="Нет изображения">
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-5">
|
||||||
|
<div class="col g-5">
|
||||||
|
<h4><span class="badge bg-secondary">Имя пользователя</span> {{name}}</h4>
|
||||||
|
<h4><span class="badge bg-secondary">Электронная почта</span> {{email}}</h4>
|
||||||
|
<h4><span class="badge bg-secondary">Текущая роль</span> {{role}}</h4>
|
||||||
|
<form action="">
|
||||||
|
<button class="btn btn-primary">Запросить права доступа</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
40
main/templates/registration/login.html
Normal file
40
main/templates/registration/login.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{% extends 'base/base.html' %}
|
||||||
|
{% block title %}
|
||||||
|
Авторизация
|
||||||
|
{% endblock %}
|
||||||
|
{% block heading %}
|
||||||
|
Авторизация
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="card mx-auto" style="width: 40rem">
|
||||||
|
<div class="card-body pb-0">
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
|
<input
|
||||||
|
required=""
|
||||||
|
class="form-control mb-3"
|
||||||
|
id="{{ field.id_for_label }}"
|
||||||
|
name="{{ field.html_name }}"
|
||||||
|
type="{{ field.widget_type }}"
|
||||||
|
/>
|
||||||
|
{% endfor %}
|
||||||
|
{% if form.non_field_errors %}
|
||||||
|
<ul class='form-errors'>
|
||||||
|
{% for error in form.non_field_errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit" class="btn btn-primary">Войти</button>
|
||||||
|
<a href="" class="btn btn-link" style="display: block;">Забыли пароль?</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -1,4 +1,82 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
from main.extra_func import set_and_get_name, set_and_get_email, load_and_get_image, set_and_get_role, check_user_exist, \
|
||||||
|
check_user_auth
|
||||||
|
from main.models import UserProfile
|
||||||
|
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from main.forms import CustomRegistrationForm
|
||||||
|
from django_registration.views import RegistrationView
|
||||||
|
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
|
from zenpy import Zenpy
|
||||||
|
|
||||||
|
|
||||||
|
class CustomRegistrationView(RegistrationView):
|
||||||
|
"""
|
||||||
|
Отображение и логика работы страницы регистрации пользователя
|
||||||
|
"""
|
||||||
|
form_class = CustomRegistrationForm
|
||||||
|
template_name = 'django_registration/registration_form.html'
|
||||||
|
success_url = reverse_lazy('django_registration_complete')
|
||||||
|
is_allowed = True
|
||||||
|
|
||||||
|
def register(self, form):
|
||||||
|
if check_user_exist(form.data['email']) and check_user_auth(form.data['email'], form.data['password_zen']):
|
||||||
|
user = User.objects.create_user(
|
||||||
|
username=form.data['username'],
|
||||||
|
email=form.data['email'],
|
||||||
|
password=form.data['password1']
|
||||||
|
)
|
||||||
|
profile = UserProfile(
|
||||||
|
image='None.png',
|
||||||
|
user=user,
|
||||||
|
role=0,
|
||||||
|
)
|
||||||
|
set_and_get_name(profile)
|
||||||
|
set_and_get_email(profile)
|
||||||
|
set_and_get_role(profile)
|
||||||
|
load_and_get_image(profile)
|
||||||
|
profile.save()
|
||||||
|
else:
|
||||||
|
self.is_allowed = False
|
||||||
|
|
||||||
|
def get_success_url(self, user=None):
|
||||||
|
"""
|
||||||
|
Возвращает url-адрес страницы, куда нужно перейти после успешной/неуспешной регистрации
|
||||||
|
Используется самой django-registration
|
||||||
|
"""
|
||||||
|
if self.is_allowed:
|
||||||
|
return reverse_lazy('django_registration_complete')
|
||||||
|
else:
|
||||||
|
return reverse_lazy('django_registration_disallowed')
|
||||||
|
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def profile_page(request):
|
||||||
|
"""
|
||||||
|
Отображение страницы профиля
|
||||||
|
|
||||||
|
|
||||||
|
:param request: объект с деталями запроса
|
||||||
|
:type request: :class:`django.http.HttpResponse`
|
||||||
|
:return: объект ответа сервера с HTML-кодом внутри
|
||||||
|
"""
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
# UP = UserProfile.objects.get(user=request.user)
|
||||||
|
UP = UserProfile.objects.get(user=request.user)
|
||||||
|
# else: # TODO: Убрать после появления регистрации и авторизации, добавить login_required()
|
||||||
|
# UP = UserProfile.objects.get(user=1)
|
||||||
|
context = {
|
||||||
|
'name': set_and_get_name(UP),
|
||||||
|
'email': set_and_get_email(UP),
|
||||||
|
'role': set_and_get_role(UP),
|
||||||
|
'image_name': load_and_get_image(UP),
|
||||||
|
'pagename': 'Страница профиля'
|
||||||
|
}
|
||||||
|
return render(request, 'pages/profile.html', context)
|
||||||
|
|
||||||
|
|
||||||
def main_page(request):
|
def main_page(request):
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
# Engine
|
# Engine
|
||||||
Django==3.1.6
|
Django==3.1.6
|
||||||
Pillow==8.1.0
|
Pillow==8.1.0
|
||||||
|
zenpy~=2.0.24
|
||||||
|
django-registration==3.1.1
|
||||||
|
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
Sphinx==3.4.3
|
Sphinx==3.4.3
|
||||||
sphinx-rtd-theme==0.5.1
|
sphinx-rtd-theme==0.5.1
|
||||||
|
|
||||||
|
BIN
static/no_avatar.png
Normal file
BIN
static/no_avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
x
Reference in New Issue
Block a user