feat: auth
This commit is contained in:
@@ -21,6 +21,21 @@ a {
|
||||
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 {
|
||||
background: #273449;
|
||||
border: solid 1px #334155;
|
||||
@@ -74,4 +89,18 @@ form {
|
||||
|
||||
.error {
|
||||
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' %}"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<img src="{% static 'logo.svg' %}" />
|
||||
<h1>Всё про IT</h1>
|
||||
<div class="auth-header">
|
||||
<div class="logo-div">
|
||||
<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>
|
||||
{% block write %}
|
||||
{% 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.http import Http404, HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
|
||||
def archive(request):
|
||||
return render(request, 'archive.html', {"posts": Article.objects.all()})
|
||||
@@ -32,3 +34,51 @@ def create_post(request):
|
||||
return render(request, 'new_article.html')
|
||||
else:
|
||||
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),
|
||||
re_path(r'^article/(?P<article_id>\d+)$', views.get_article, name='get_article'),
|
||||
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