feat: auth
This commit is contained in:
@@ -21,6 +21,21 @@ a {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auth-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-div {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-sep {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
.one-post {
|
.one-post {
|
||||||
background: #273449;
|
background: #273449;
|
||||||
border: solid 1px #334155;
|
border: solid 1px #334155;
|
||||||
@@ -74,4 +89,18 @@ form {
|
|||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: red;
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
max-width: 400px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registration-header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registration-error {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,23 @@
|
|||||||
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
|
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="auth-header">
|
||||||
<img src="{% static 'logo.svg' %}" />
|
<div class="logo-div">
|
||||||
<h1>Всё про IT</h1>
|
<img src="{% static 'logo.svg' %}" />
|
||||||
|
<h1>Всё про IT</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{% block auth %}
|
||||||
|
{% if not user.is_anonymous %}
|
||||||
|
<a href="/logout/">Выйти</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/login/">Вход</a>
|
||||||
|
<p class="login-sep">/</p>
|
||||||
|
<a href="/registration/">Регистрация</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% block write %}
|
{% block write %}
|
||||||
{% if not user.is_anonymous %}
|
{% if not user.is_anonymous %}
|
||||||
|
|||||||
29
articles/templates/login.html
Normal file
29
articles/templates/login.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Регистрация</title>
|
||||||
|
{% load static %}
|
||||||
|
<link rel="stylesheet" href="{% static 'index.css' %}">
|
||||||
|
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<img src="{% static 'logo.svg' %}" />
|
||||||
|
<h1>Всё про IT</h1>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<h1 class="registration-header">Вход</h1>
|
||||||
|
<form class="login-form" method="POST">{% csrf_token %}
|
||||||
|
<input class="username" type="username" name="username" placeholder="Имя пользователя" value="{{ form.username}}">
|
||||||
|
<input class="password" type="password" name="password" placeholder="Пароль" value="{{ form.password }}">
|
||||||
|
<input class="submit" type="submit" value="Войти">
|
||||||
|
</form>
|
||||||
|
<div class="error registration-error">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p><a href="/">← Назад к списку статей</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
30
articles/templates/registration.html
Normal file
30
articles/templates/registration.html
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Регистрация</title>
|
||||||
|
{% load static %}
|
||||||
|
<link rel="stylesheet" href="{% static 'index.css' %}">
|
||||||
|
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<img src="{% static 'logo.svg' %}" />
|
||||||
|
<h1>Всё про IT</h1>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<h1 class="registration-header">Регистрация</h1>
|
||||||
|
<form class="login-form" method="POST">{% csrf_token %}
|
||||||
|
<input class="username" type="username" name="username" placeholder="Имя пользователя" value="{{ form.username}}">
|
||||||
|
<input class="email" name="email" placeholder="Почта" value="{{ form.email }}">
|
||||||
|
<input class="password" type="password" name="password" placeholder="Пароль" value="{{ form.password }}">
|
||||||
|
<input class="submit" type="submit" value="Зарегистрироваться">
|
||||||
|
</form>
|
||||||
|
<div class="error registration-error">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p><a href="/">← Назад к списку статей</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -2,6 +2,8 @@ from .models import Article
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import Http404, HttpResponse
|
from django.http import Http404, HttpResponse
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth import authenticate, login, logout
|
||||||
|
|
||||||
def archive(request):
|
def archive(request):
|
||||||
return render(request, 'archive.html', {"posts": Article.objects.all()})
|
return render(request, 'archive.html', {"posts": Article.objects.all()})
|
||||||
@@ -32,3 +34,51 @@ def create_post(request):
|
|||||||
return render(request, 'new_article.html')
|
return render(request, 'new_article.html')
|
||||||
else:
|
else:
|
||||||
return HttpResponse('Unauthorized', status=401)
|
return HttpResponse('Unauthorized', status=401)
|
||||||
|
|
||||||
|
def registration(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
form = { 'username': request.POST["username"], 'email': request.POST["email"], 'password': request.POST["password"] }
|
||||||
|
username = request.POST.get("username", "").strip()
|
||||||
|
email = request.POST.get("email", "").strip()
|
||||||
|
password = request.POST.get("password", "").strip()
|
||||||
|
if not username or not email or not password:
|
||||||
|
return render(request, 'registration.html', {'error': 'Все поля обязательны для заполнения.', 'form': form})
|
||||||
|
|
||||||
|
if len(password) < 6:
|
||||||
|
return render(request, 'registration.html', {'error': 'Пароль должен содержать не менее 6 символов.', 'form': form})
|
||||||
|
|
||||||
|
if User.objects.filter(username=username).exists():
|
||||||
|
return render(request, 'registration.html', {'error': 'Пользователь с таким именем уже существует.', 'form': form})
|
||||||
|
|
||||||
|
if User.objects.filter(email=email).exists():
|
||||||
|
return render(request, 'registration.html', {'error': 'Этот email уже используется.', 'form': form})
|
||||||
|
|
||||||
|
if "@" not in email or "." not in email:
|
||||||
|
return render(request, 'registration.html', {'error': 'Некорректный формат email.', 'form': form})
|
||||||
|
|
||||||
|
user = User.objects.create_user(username=username, email=email, password=password)
|
||||||
|
user.save()
|
||||||
|
return redirect('/login')
|
||||||
|
return render(request, 'registration.html')
|
||||||
|
|
||||||
|
def login_page(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
form = {'username': request.POST.get("username"), 'password': request.POST.get("password")}
|
||||||
|
username = request.POST.get("username", "").strip()
|
||||||
|
password = request.POST.get("password", "").strip()
|
||||||
|
|
||||||
|
if not username or not password:
|
||||||
|
return render(request, 'login.html', {'error': 'Введите имя пользователя и пароль.', 'form': form})
|
||||||
|
|
||||||
|
user = authenticate(request, username=username, password=password)
|
||||||
|
|
||||||
|
if user is None:
|
||||||
|
return render(request, 'login.html', {'error': 'Неверное имя пользователя или пароль.', 'form': form})
|
||||||
|
|
||||||
|
login(request, user)
|
||||||
|
return redirect('/')
|
||||||
|
return render(request, 'login.html')
|
||||||
|
|
||||||
|
def user_logout(request):
|
||||||
|
logout(request)
|
||||||
|
return redirect('/')
|
||||||
@@ -23,4 +23,7 @@ urlpatterns = [
|
|||||||
path('', views.archive),
|
path('', views.archive),
|
||||||
re_path(r'^article/(?P<article_id>\d+)$', views.get_article, name='get_article'),
|
re_path(r'^article/(?P<article_id>\d+)$', views.get_article, name='get_article'),
|
||||||
path('article/new/', views.create_post),
|
path('article/new/', views.create_post),
|
||||||
|
path('registration/', views.registration),
|
||||||
|
path('login/', views.login_page),
|
||||||
|
path('logout/', views.user_logout),
|
||||||
]
|
]
|
||||||
|
|||||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Reference in New Issue
Block a user