Создание страницы регистрации пользователей Django в Python

В этом уроке вы узнаете, как создать в Python форму регистрации и страницы входа в Django, которая позволит пользователям зарегистрироваться.

Содержание

Создание формы регистрации Django

Сначала определите URL-адрес регистрации в urls.py приложения пользователя:

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.sign_in, name='login'),
    path('logout/', views.sign_out, name='logout'),
    path('register/', views.sign_up, name='register'),
]

Во-вторых, определите класс RegisterForm в forms.py файла users.py:

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm


class LoginForm(forms.Form):
    username = forms.CharField(max_length=65)
    password = forms.CharField(max_length=65, widget=forms.PasswordInput)
    

class RegisterForm(UserCreationForm):
    class Meta:
        model=User
        fields = ['username','email','password1','password2'] 
   

RegisterForm использует встроенную модель User и включает четыре поля, включая имя пользователя, адрес электронной почты, пароль1 и пароль2, которые пользователь должен заполнить для регистрации.

В-третьих, определите функцию представления sign_up() в файле views.py приложения пользователя:

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from .forms import LoginForm, RegisterForm

def sign_up(request):
    if request.method == 'GET':
        form = RegisterForm()
        return render(request, 'users/register.html', { 'form': form})   

Функция представления sign_up() создает объект RegisterForm и отображает его в шаблоне register.html.

В-четвертых, создайте шаблон register.html в каталоге templates/users приложения users:

{% extends 'base.html' %}

{% block content %}

<form method="POST" novalidate>
	{% csrf_token %}
	<h2>Sign Up</h2>
	{{ form.as_p }}		
	<input type="submit" value="Register" />
</form>

{% endblock content%}

Registerl.html расширяет шаблон base.html проекта. Он отображает RegisterForm(форму).

Обратите внимание, что свойство novalidate удаляет проверку HTML5. После завершения проекта вы можете удалить это свойство, чтобы включить проверку HTML5.

Наконец, откройте URL-адрес регистрации:

http://127.0.0.1:8000/register/

…вы увидите следующую форму регистрации:

Форма регистрации django - по умолчанию

Настройка формы регистрации Django

Регистрационная форма имеет четыре поля с большим количеством информации. Эта информация берется из модели User по умолчанию.

Если вы хотите настроить информацию, отображаемую в форме, вы можете изменить шаблон register.html следующим образом:

{% extends 'base.html' %}

{% block content %}
<form method="POST" novalidate>
	{% csrf_token %}
	<h2>Sign Up</h2>
		
	{% for field in form %}
	<p>
		{% if field.errors %}
		<ul class="errorlist">
			{% for error in field.errors %}
			<li>{{ error }}</li>
			{% endfor %}
		</ul>
		{% endif %}
	 	{{ field.label_tag }} {{ field }}
	</p>
	{% endfor %}
	<input type="submit" value="Register" />
</form>
{% endblock content%}

Шаблон перебирает поля формы и выводит каждое поле по отдельности. Для каждого поля он отображает список ошибок, если проверка не пройдена.

Новая форма будет выглядеть так:

Регистрационная форма djang – настройка

Если вы заполните информацию и нажмете «Зарегистрироваться», вы получите сообщение об ошибке, поскольку мы не добавили код, обрабатывающий HTTP-запрос POST.

Обработка логики регистрации

Для обработки HTTP-запроса POST необходимо изменить функцию sign_up() в файле views.py приложения пользователя:

def sign_up(request):
    if request.method == 'GET':
        form = RegisterForm()
        return render(request, 'users/register.html', {'form': form})    
   
    if request.method == 'POST':
        form = RegisterForm(request.POST) 
        if form.is_valid():
            user = form.save(commit=False)
            user.username = user.username.lower()
            user.save()
            messages.success(request, 'You have singed up successfully.')
            login(request, user)
            return redirect('posts')
        else:
            return render(request, 'users/register.html', {'form': form})

Как это работает.

Сначала создайте новый экземпляр RegisterForm:

form = RegisterForm(request.POST)

Если форма действительна, мы сохраняем форму, но не сохраняем ее немедленно в базе данных. Это делается путем передачи аргумента commit=False в метод save() объекта формы.

Причина в том, что мы хотим сделать имя пользователя строчным перед сохранением его в базе данных:

user.username = user.username.lower()
user.save()

После сохранения пользователя мы создаем флэш-сообщение, авторизуем пользователя и перенаправляем его на страницу списка сообщений:

messages.success(request, 'You have singed up successfully.')
login(request, user)
return redirect('posts')

Если форма недействительна, мы перерисовываем форму с ранее введенными значениями, передавая объект формы в функцию render():

return render(request, 'users/register.html', {'form': form})

Следующий пример иллюстрирует, как зарегистрировать пользователя с именем jane:

Пример регистрации пользователя с именем janeПример успешной регистрации

Добавление ссылок

  • Сначала включите ссылку на регистрацию, изменив шаблон base.html. Также включите ссылки «Мои записи» и «Новая запись», если пользователь вошел в систему:
{%load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="{% static 'css/style.css' %}" />
    <script src="{% static 'js/app.js' %}" defer></script>
    <title>My Site</title>
  </head>
  <body>
  	<header>
  		{%if request.user.is_authenticated %}
  			<a href="{% url 'posts' %}">My Posts</a>
  			<a href="{% url 'post-create' %}">New Post</a>
  			<span>Hi {{ request.user.username | title }}</span>
  			<a href="{% url 'logout' %}">Logout</a>
  		{%else%}
  			<a href="{% url 'login' %}">Login</a>
  			<a href="{% url 'register' %}">Register</a>
  		{%endif%}
  	</header>
  	<main>
	  	{% if messages %}
			<div class="messages">
			{% for message in messages %}
				<div class="alert {% if message.tags %}alert-{{ message.tags }}"{% endif %}>
					{{ message }}
				</div>
			{% endfor %}
			</div>
		{% endif %}
		    
	    {%block content%} 
	    {%endblock content%}
  	</main>
	
  </body>
</html>

Окно регистрации

  • Во-вторых, включите ссылку на регистрацию в шаблон login.html:
{% extends 'base.html' %}

{% block content %}
<form method="POST" novalidate>
	{% csrf_token %}
	<h2>Login</h2>
	{{form.as_p}}
	<input type="submit" value="Login" />
	<p>Don't have an account? <a href="{%url 'register' %}">Register</a></p>
</form>

{% endblock content%}

Ссылка на регистрацию

  • В-третьих, добавьте ссылку для входа на страницу register.html:
{% extends 'base.html' %}

{% block content %}
<form method="POST" novalidate>
	{% csrf_token %}
	<h2>Sign Up</h2>
		
	{% for field in form %}
	<p>
		{% if field.errors %}
		<ul class="errorlist">
			{% for error in field.errors %}
			<li>{{ error }}</li>
			{% endfor %}
		</ul>
		{% endif %}
	 	{{ field.label_tag }} {{ field }}
	</p>
	{% endfor %}
	<input type="submit" value="Register" />
	<p>Already has an account? <a href="{%url 'login' %}">Login</a></p>
</form>
{% endblock content%}

Пример ссылки для входа на страницу register.html

Запрет пользователю редактировать/удалять сообщения других пользователей

Обычно пользователь не должен иметь возможности редактировать или удалять посты других пользователей. Однако пользователь может просматривать посты других пользователей.

Для реализации этой функции нам нужно проверить, является ли автор поста тем же, что и авторизованный в данный момент пользователь. Если да, мы отображаем формы редактирования/удаления. В противном случае мы можем перенаправить пользователей на страницу 404.

Также нам необходимо скрыть ссылки редактирования и удаления на странице списка сообщений, если сообщения не принадлежат пользователю.

Сначала измените views.py приложения блога:

from django.shortcuts import render,redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import  login_required
from .models import Post
from .forms import PostForm

@login_required
def delete_post(request, id):
    queryset = Post.objects.filter(author=request.user)
    post = get_object_or_404(queryset, pk=id)
    context = {'post': post}    
    
    if request.method == 'GET':
        return render(request, 'blog/post_confirm_delete.html',context)
    elif request.method == 'POST':
        post.delete()
        messages.success(request,  'The post has been deleted successfully.')
        return redirect('posts')        

@login_required    
def edit_post(request, id):
    queryset = Post.objects.filter(author=request.user)
    post = get_object_or_404(queryset, pk=id)

    if request.method == 'GET':
        context = {'form': PostForm(instance=post), 'id': id}
        return render(request,'blog/post_form.html',context)
    
    elif request.method == 'POST':
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            messages.success(request, 'The post has been updated successfully.')
            return redirect('posts')
        else:
            messages.error(request, 'Please correct the following errors:')
            return render(request,'blog/post_form.html',{'form':form})

@login_required
def create_post(request):
    if request.method == 'GET':
        context = {'form': PostForm()}
        return render(request,'blog/post_form.html',context)
    elif request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'The post has been created successfully.')
            return redirect('posts')
        else:
            messages.error(request, 'Please correct the following errors:')
            return render(request,'blog/post_form.html',{'form':form})          
    

def home(request):
    posts = Post.objects.all()
    context = {'posts': posts  }
    return render(request,'blog/home.html', context)   

И при удалении, и при обновлении мы фильтруем публикацию по текущему пользователю, прежде чем передать ее в функцию get_object_or_404().

Если вы войдете в систему как Джейн и попытаетесь отредактировать пост, который не принадлежит Джейн, вы получите ошибку 404. Например:

Запрет редактирования

Страница 404:

Пример получения ошибки 404

Во-вторых, измените шаблон home.html, чтобы скрыть ссылки редактирования и удаления.

{% extends 'base.html' %}
	
{% block content %}
<h1>My Posts</h1>
	{% for post in posts %}
		<h2>{{ post.title }}</h2>
		<small>Published on {{ post.published_at | date:"M d, Y" }} by {{ post.author | title}}</small>
		<p>{{ post.content }}</p>
		
		{% if request.user.is_authenticated and request.user == post.author %}
		<p>
			<a href="{% url 'post-edit' post.id %}">Edit</a> 
			<a href="{% url 'post-delete' post.id%}">Delete</a>
		</p>
		{% endif %}
		
	{% endfor %}
{% endblock content %}

Удаление автора из формы создания поста

Сначала удалите поле автора из полей класса PostForm:

from django.forms import ModelForm
from .models import Post

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ['title','content']    

Форма после создания будет выглядеть так:

Пример удаления данных автора

Во-вторых, измените функцию create_post() в файле views.py приложения блога, чтобы обновить автора поста до текущего вошедшего в систему пользователя:

@login_required
def create_post(request):
    if request.method == 'GET':
        context = {'form': PostForm()}
        return render(request,'blog/post_form.html',context)
    elif request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.author = request.user
            user.save()
            messages.success(request, 'The post has been created successfully.')
            return redirect('posts')
        else:
            messages.error(request, 'Please correct the following errors:')
            return render(request,'blog/post_form.html',{'form':form})  
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *