0% found this document useful (0 votes)
14 views22 pages

Django Blog Setup and User Registration

1. This document outlines the steps to create a basic blog application using Django, including installing Django, creating a project and app, setting up models, views, templates, and the admin interface. 2. It describes how to display blog posts from a database using templates, add user registration and authentication, and style the forms with Crispy Forms. 3. The key steps are: installing Django, creating a project and app, setting up models, views and templates to display data, registering the models with the admin interface, adding user registration and authentication, and styling forms with Crispy Forms.

Uploaded by

Habtamu Asayto
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views22 pages

Django Blog Setup and User Registration

1. This document outlines the steps to create a basic blog application using Django, including installing Django, creating a project and app, setting up models, views, templates, and the admin interface. 2. It describes how to display blog posts from a database using templates, add user registration and authentication, and style the forms with Crispy Forms. 3. The key steps are: installing Django, creating a project and app, setting up models, views and templates to display data, registering the models with the admin interface, adding user registration and authentication, and styling forms with Crispy Forms.

Uploaded by

Habtamu Asayto
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

1.

Install django
pip install django

- Show version of django


python -m django --version
2. Create project
django-admin startproject django_project
3. Run project
python [Link] runserver
4. Create new app
python [Link] startapp blog

- Go to [Link] then import http and create a function


from [Link] import render
from [Link] import HttpResponse

def home(request):
return HttpResponse("<h1>Home page</h1>")

- Create [Link] file inside of blog


from [Link] import path
from . import views

urlpatterns = [
path('',[Link])
]

[Link] of django_project
from [Link] import admin
from [Link] import path, include

urlpatterns = [
path('admin/', [Link]),
path('blog/', include('[Link]'))
]

5. Create template(for html)


- create a folder template inside of blog and inside template add
folder blog (create html files inside that)
- Add that html and before that
- INSTALLED_APPS = [
'[Link]',
And
def about(request):
return render(request,'blog/[Link]')

6. Display a data from post


[Link]
from [Link] import render
from [Link] import HttpResponse
posts = [
{
'author' : 'Habtamu Asayto',
'title' : 'The first post',
'content' : 'The whole content of the first blog post',
'posted_date' : 'February 12, 2024'
},
{
'author' : 'Some One',
'title' : 'The second post',
'content' : 'The whole content of the 2ns blog post',
'posted_date' : 'September 12, 2025'
}
]
def index(request):
context = {
'posts' : posts
}
return render(request, 'blog/[Link]', context)

def about(request):
return render(request,'blog/[Link]',{'title': 'About'})

[Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% if title %}
<title>Django blog {{ title }}</title>
{% else %}
<title>Django blog</title>
{% endif %}

</head>
<body>
{% for post in posts %}
<h1>{{ [Link] }}</h1>
<p>By {{ [Link] }} on {{ post.posted_date }}</p>
<p> {{ [Link] }} </p>
{% endfor %}
</body>
</html>

[Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% if title %}
<title>Django blog - {{ title }}</title>
{% else %}
<title>Django blog</title>
{% endif %}
</head>
<body>
<h1>About page</h1>
</body>
</html>
7. Create a [Link] file used as a parent html file, then index and
about files are inheriting from base
[Link]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% if title %}
<title>Django blog - {{ title }}</title>
{% else %}
<title>Django blog</title>
{% endif %}
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>

[Link]

{% extends "blog/[Link]" %}
{% block content %}
{% for post in posts %}
<h1>{{ [Link] }}</h1>
<p>By {{ [Link] }} on {{ post.posted_date }}</p>
<p> {{ [Link] }} </p>
{% endfor %}
{% endblock content %}

8. Add bootstrap and css


9. Create admin user
python [Link] createsuperuser
- There error
[Link]: no such table: auth_user
- To fix the above error, migrate
python [Link] makemigrations
python [Link] migrate
10. Database and migration
[Link]
from [Link] import models
from [Link] import timezone
from [Link] import User # many post to one user
relationship between users and the model
class Post([Link]):
title = [Link](max_length=255),
content = [Link](),
posted_date = [Link](default=[Link]),
author = [Link](User, on_delete=[Link])

then,
python [Link] makemigrations blog
python [Link] sqlmigrate blog 0001
python [Link] migrate

python [Link] shell


from [Link] import Post
from [Link] import User

[Link]()
[Link]()
[Link](username='habtamu')
[Link](username='habtamu').first() # assign this to
user variable

user = [Link](username='habtamu').first()
user
[Link] = [Link]

>>> user = [Link](id=1)


>>> user

Now continue to table Post


post_1 = Post(title='Blog Post 1',content='Content of blog post
1',author=user)
post_1.save()
[Link]()

>>> post = [Link]()


>>> [Link]
>>> [Link]
<User: Habtamu>
>>> [Link]
'habtamuasayto360@[Link]'

>>> user.post_set
>>> user.post_set.all()
>>> user.post_set.create(title='Blog Post 3', content='The content
of blog post 3')
>>> [Link]()

Now, display this inserted database to views


[Link]
from .models import Post

def index(request):
context = {
'posts' : [Link]()
}
return render(request, 'blog/[Link]', context)

Date format
[Link]
<small class="text-muted">{{ post.posted_date|date:"F d,
Y" }}</small>

Register the Post blog to [Link]


[Link]
from [Link] import admin
from .models import Post

[Link](Post)

- To add a post inside admin of blog


[Link]
from [Link] import admin
from .models import Post

[Link](Post)

11. Registration form

Create new users


python [Link] startapp users
then, add into INSTALLED_APPS on [Link]
'[Link]',

Go to [Link] and add a function register


[Link]
from [Link] import render, redirect
from [Link] import UserCreationForm
from [Link] import messages

def register(request):
if [Link] == 'POST':
form = UserCreationForm([Link])
if form.is_valid():
[Link]()
username = form.cleaned_data.get('username')
[Link](request,f"Account created for
{username}!")
return redirect('blog-home')
else:
form = UserCreationForm()
return render(request, 'users/[Link]', {'form':form})

[Link]
{% extends "blog/[Link]" %}
{% block content %}
<div class="content-section">
<form method="post">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">
Signup here
</legend>
{{ form.as_p }}
</fieldset>

<div class="form-group">
<button class="btn btn-outline-info"
type="submit">Signup</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">Aready have account <a
href="#" class="ml-2">SignIn</a></small>
</div>
</div>
{% endblock content %}

Main [Link]
from [Link] import admin
from [Link] import path, include
from users import views as user_views

urlpatterns = [
path('admin/', [Link]),
path('register/', user_views.register, name='register'),
path('blog/', include('[Link]')),
]

[Link] inside of blog


<div class="col-md-8">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{[Link]}}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% block content %}
{% endblock %}
</div>

The above one has only username and password, to add other attribute
- Create [Link] insides of users app

from django import forms


from [Link] import User
from [Link] import UserCreationForm

class UserRegisterForm(UserCreationForm):
email = [Link]()

class Meta:
model = User
fields = ['username','email','password1','password2']

and change [Link]

from [Link] import render, redirect


from [Link] import messages
from .forms import UserRegisterForm

def register(request):
if [Link] == 'POST':
form = UserRegisterForm([Link])
if form.is_valid():
[Link]()
username = form.cleaned_data.get('username')
[Link](request,f"Account created for
{username}!")
return redirect('blog-home')
else:
form = UserRegisterForm()
return render(request, 'users/[Link]', {'form':form})

12. Crispy form (to create awesome from in bootstrap)


- Install it
pip install django-crispy-forms
pip install crispy-bootstrap4
- Go to setting
'crispy_forms',
'crispy_bootstrap4',
CRISPY_TEMPLATE_PACK = 'bootstrap4'
- Load it above [Link]
{% load crispy_forms_tags %}
{{ form|crispy }}

13. Login and Logout


- Import auth_views on [Link]
from [Link] import views as auth_views

path('login/',auth_views.LoginView.as_view(template_name='users/[Link]'
), name='login'),
path('logout/',auth_views.LogoutView.as_view(template_name='users/
[Link]'), name='logout'),

- Create [Link] inside users template


{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Login
</legend>
{{ form|crispy }}
</fieldset>

<div class="form-group">
<button class="btn btn-outline-info"
type="submit">Login</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">Haven't an account ? <a
href="{% url 'register' %}" class="ml-2">Signup Here</a></small>
</div>
</div>
{% endblock content %}

- Add redirect at the end of [Link]


LOGIN_REDIRECT_URL = 'blog-home'

[Link]
{% extends "blog/[Link]" %}
{% block content %}
<h2>You have logged out</h2>
<div class="border-top pt-3">
<small class="text-muted">
<a href="{% url 'login' %}" class="ml-2">Sign in</a>
</small>
</div>
{% endblock content %}
[Link]
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" href="{% url 'logout'
%}">Logout</a>
{% else %}
<a class="nav-item nav-link" href="{% url 'login'
%}">Login</a>
<a class="nav-item nav-link" href="{% url 'register'
%}">Register</a>
{% endif %}
</div>

- Add profile function inside of users [Link]


def profile(request):
return render(request, 'users/[Link]')

[Link] inside template

{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<h2>{{ [Link] }}</h2>
{% endblock content %}

[Link]
path('profile/', user_views.profile, name='profile'),

[Link]
<div class="navbar-nav">
{% if user.is_authenticated %}
<a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a>
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% else %}
<a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
<a class="nav-item nav-link" href="{% url 'register' %}">Register</a>
{% endif %}
</div>

- Login required pages


[Link] of users
from [Link] import login_required

@login_required
def profile(request):
return render(request, 'users/[Link]')

[Link]
LOGIN_URL = 'login'

14. Profile
[Link]
from [Link] import models
from [Link] import User
class Profile([Link]):
user = [Link](User, on_delete=[Link])
image =
[Link](default='[Link]',upload_to='profile_pics')

def __str__(self):
return f'{[Link]} Profile'

To migrate Models
python [Link] makemigrations
python -m pip install Pillow
python [Link] makemigrations
python [Link] migrate

To compile locale
python [Link] makemessages
python [Link] complilemessages

[Link] inside users, to add Admin page


from [Link] import admin
from .models import Profile

[Link](Profile)

- Access Profile attribute on the views


python [Link] shell
>>> from [Link] import User
>>> [Link]()
>>> user = [Link](username='Habtamu').first()
>>> [Link]
profile_pics directory inside the project is created
- Change the path of media on [Link], then I will store profile
pictures == media/profile_pics path
MEDIA_ROOT = [Link](BASE_DIR, 'media') # to access the media
from our pc on browser
MEDIA_URL = '/media/'

- To display profile info on the view


[Link]

{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img"
src="{{ [Link] }}">
<div class="media-body">
<h2 class="account-heading">{{ [Link] }}</h2>
<p class="text-secondary">{{ [Link] }} </p>
</div>
</div>
</div>
{% endblock content %}

- To display profile image, we must fix on [Link]

from [Link] import settings


from [Link] import static
if [Link]:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)

- Create [Link] file on users folder


from [Link] import post_save
from [Link] import User
from [Link] import receiver
from .models import Profile

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
[Link](user=instance)

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
[Link]()

[Link] on users folder


def ready(self):
import [Link]

15. Update User profile


- Inside [Link]
from .models import Profile

class UserUpdateForm([Link]):
email = [Link]()

class Meta:
model = User
fields = ['username', 'email']

class ProfileUpdateForm([Link]):
class Meta:
model = Profile
fields = ['image']

[Link]
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm

@login_required
def profile(request):
u_form = UserUpdateForm()
p_form = ProfileUpdateForm()
context = {
'u_form': u_form,
'p_form' : p_form
}
return render(request, 'users/[Link]' , context)

[Link]

{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img style="width:70px;height:70px;margin-right:7px"
class="rounded-circle account-img" src="{{ [Link] }}" />
<div class="media-body">
<h2 class="account-heading">{{ [Link] }}</h2>
<p class="text-secondary">{{ [Link] }} </p>
</div>
</div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Profile
information</legend>
{{ u_form|crispy }}
{{ p_form|crispy }}
</fieldset>

<div class="form-group">
<button class="btn btn-outline-info"
type="submit">Update</button>
</div>
</form>
</div>
{% endblock content %}

On [Link]
Add instance based on POST or not
from [Link] import render, redirect
from [Link] import messages
from [Link] import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm

def register(request):
if [Link] == 'POST':
form = UserRegisterForm([Link])
if form.is_valid():
[Link]()
username = form.cleaned_data.get('username')
[Link](request,f"{username} Your account are created
successfully, Login now !")
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/[Link]', {'form':form})

@login_required
def profile(request):
if [Link] == 'POST':
u_form = UserUpdateForm([Link], instance = [Link])
p_form = ProfileUpdateForm([Link], [Link], instance =
[Link])
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
[Link](request, f"Your account has updated
successfully !")
return redirect('profile')
else:
u_form = UserUpdateForm(instance = [Link])
p_form = ProfileUpdateForm(instance = [Link])
context = {
'u_form': u_form,
'p_form' : p_form
}
return render(request, 'users/[Link]', context)

- Resize image size


[Link]
from [Link] import models
from [Link] import User
from PIL import Image

class Profile([Link]):
user = [Link](User, on_delete=[Link])
image =
[Link](default='[Link]',upload_to='profile_pics')

def __str__(self):
return f'{[Link]} Profile'

def save(self):
super().save()

img = [Link]([Link])
if [Link] > 300 or [Link] > 300:
output_size = (300, 300)
[Link](output_size)
[Link]([Link])

- Add image on the home page of each cards


[Link]
<img style="width:80px;height:80px;margin-right:7px" class="rounded-circle
article-img" src="{{ [Link] }}"/>

16. CRUD
- Create Create, Display, Update and Delete functions on blog
[Link]
from [Link] import ListView

Display

class PostListView(ListView):
model = Post
template_name='blog/[Link]'
context_object_name = 'posts'
ordering = ['-posted_date'] # Display based on the date

[Link] on blog
from [Link] import path
from .views import PostListView
from . import views

urlpatterns = [
#path('',[Link], name='blog-home'),
path('',PostListView.as_view(), name='blog-home'),
path('about/',[Link], name='blog-about')
]

- To create Detail View


[Link]
from [Link] import ListView, DetailView

path('post/<int:pk>/',PostDetailView.as_view(), name='post-detail'),

create post_detail.html on blog template

{% extends "blog/[Link]" %}
{% block content %}
<div class="card" style="margin-top: 19px;">
<h5 class="card-header">
<div class="article-metadata">
<img style="width:80px;height:80px;margin-right:7px"
class="rounded-circle article-img"
src="{{ [Link] }}"/>
<a class="mr-2" href="#">{{ [Link] }}</a>
<small class="text-muted">{{ object.posted_date|date:"F
d, Y" }}</small>
</div>
</h5>
<div class="card-body">
<h3><a class="article-title" href="#">{{ [Link] }}</a>
</h3>
<p class="article-content">{{ [Link] }}</p>
</div>
</div>

{% endblock content %}

- Go to Post detail page when we press one Post


[Link]
<h3><a class="article-title" href="{% url 'post-detail' [Link]
%}">{{ [Link] }}</a> </h3>

- Create New post on View (inside of blog app)


[Link]
from [Link] import ListView, DetailView, CreateView

class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']

[Link]
from .views import PostListView, PostDetailView, PostCreateView
- Create post_form.html file inside blog template
Post_form.html
{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">
Create Blog post
</legend>
{{ form|crispy }}
</fieldset>

<div class="form-group">
<button class="btn btn-outline-info"
type="submit">Post</button>
</div>
</form>

</div>
{% endblock content %}

- When we run, fill and submit the project, then NOT NULL constraint
failed:, so we must add on [Link]
[Link]
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']

def form_valid(self,form):
[Link] = [Link]
return super().form_valid(form)

[Link] on blog
from [Link] import reverse

def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': [Link]})

- Now it create new post and redirect to its own created post

- Another way to redirect post/new to login page if not logged

[Link]
from [Link] import LoginRequiredMixin # redirect to
login

class PostCreateView(LoginRequiredMixin, CreateView):


- Update
[Link]
from [Link] import ListView, DetailView, CreateView,
UpdateView

#Update
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
fields = ['title', 'content']

def form_valid(self,form):
[Link] = [Link]
return super().form_valid(form)

[Link]
from .views import PostListView, PostDetailView, PostCreateView,
PostUpdateView

path('post/<int:pk>/update',PostUpdateView.as_view(), name='post-update'),

- Delete a post
[Link]
from [Link] import ListView, DetailView, CreateView,
UpdateView, DeleteView

#Delete
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post

def test_func(self):
post = self.get_object()
if [Link] == [Link]:
return True
return False

[Link]
from .views import PostListView, PostDetailView, PostCreateView,
PostUpdateView, PostDeleteView

path('post/<int:pk>/delete',PostDeleteView.as_view(), name='post-delete'),

- Confirm delete, Create delete_confirm.html


Post_delete_confirm.html
{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">
Delete Post
</legend>
<h2>Are your sure to delete post "{{ [Link] }}"? </h2>
</fieldset>

<div class="form-group">
<button class="btn btn-outline-danger"
type="submit">Delele</button>
<a class="btn btn-outline-secondary" href="{% url 'post-
detail' [Link] %}">Cancel</a>

</div>
</form>

</div>
{% endblock content %}

- To get success_url
[Link], inside of PostDeleteView function
success_url = '/blog/'

[Link]
<a class="nav-item nav-link" href="{% url 'post-create' %}">New Post</a>
<a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a>
<a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
Post_detail.html
{% if [Link] == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'post-
update' [Link] %}"> Update </a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'post-
delete' [Link] %}"> Delete </a>
</div>
{% endif %}

17. Pagination
- Create [Link] file on and go to shell
>>> from [Link] import Paginator
>>> posts = ['1','2','3','4','5']
>>> p = Paginator(posts,2)
>>> p.num_pages
>>> for page in p.page_range:
... print(page)
...
1
2
3
>>>
>>>
>>> p1= [Link](1)
>>> p1
>>> [Link]
>>> p1.object_list
>>> p1.has_previous()
>>> p1.has_next()

[Link]
Add on PostListView Function
paginate_by = 2
at the end of [Link] on blog
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?
page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < [Link]|
add:'3' %}
<a class="btn btn-outline-info mb-4" href="?
page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}

{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}

{% endif %}

[Link] for cruding users


from [Link] import render, get_object_or_404
from [Link] import User

#Display Users
class UserPostListView(LoginRequiredMixin, ListView):
model = Post
template_name='blog/user_post.html'
context_object_name = 'posts'
ordering = ['-posted_date'] # Display based on the date
paginate_by = 2

def get_queryset(self):
user=get_object_or_404(User, username=[Link]('username'))
return [Link](author=user).order_by('-posted_date')

Create user_post.html

{% extends "blog/[Link]" %}
{% block content %}
<h2 class="mb-3">Posts by {{ [Link] }}
({{ page_obj.[Link] }})</h2>
{% for post in posts %}
<div class="card" style="margin-top: 19px;">
<h5 class="card-header">
<div class="article-metadata">
<img style="width:80px;height:80px;margin-
right:7px" class="rounded-circle article-img"
src="{{ [Link] }}"/>
<a class="mr-2" href="{% url 'user-posts'
[Link] %}">{{ [Link] }}</a>
<small class="text-muted">{{ post.posted_date|
date:"F d, Y" }}</small>
</div>
</h5>
<div class="card-body">
<h3><a class="article-title" href="{% url 'post-detail'
[Link] %}">{{ [Link] }}</a> </h3>
<p class="article-content">{{ [Link] }}</p>
</div>
</div>
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?
page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num <
[Link]|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?
page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}

{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?
page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}

{% endif %}
{% endblock content %}

[Link]
<a class="mr-2" href="{% url 'user-posts' [Link]
%}">{{ [Link] }}</a>

[Link]
from .views import PostListView, PostDetailView, PostCreateView,
PostUpdateView, PostDeleteView, UserPostListView

path('user/<username>',UserPostListView.as_view(), name='user-posts'),

18. Email and password reset


Go to project url
[Link]
path('password-reset/',
auth_views.PasswordResetView.as_view(template_name='users/password_reset.ht
ml'), name='password_reset'),

create password_reset.html inside users app


{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Request
Password Reset</button>
</div>
</form>
</div>
{% endblock content %}

Password_reset_confirm.html
{% extends "blog/[Link]" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Reset
Password</button>
</div>
</form>
</div>
{% endblock content %}

Password_reset_done.html
{% extends "blog/[Link]" %}
{% block content %}
<div class="alert alert-info">
An email has been sent with instructions to reset your password
</div>
{% endblock content %}

And on [Link]
path('password-reset/done/',

auth_views.PasswordResetDoneView.as_view(template_name='users/password_rese
t_done.html'),name='password_reset_done'),

Then, it needs confirm, so create password_reset_complete.html file


{% extends "blog/[Link]" %}
{% block content %}
<div class="alert alert-info">
Your password has been set.
</div>
<a href="{% url 'login' %}">Sign In Here</a>
{% endblock content %}
[Link]

path('password-reset/',
auth_views.PasswordResetView.as_view(
template_name='users/password_reset.html'
),
name='password_reset'),
path('password-reset/done/',
auth_views.PasswordResetDoneView.as_view(
template_name='users/password_reset_done.html'
),
name='password_reset_done'),
path('password-reset-confirm/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(
template_name='users/password_reset_confirm.html'
),
name='password_reset_confirm'),
path('password-reset-complete/',
auth_views.PasswordResetCompleteView.as_view(
template_name='users/password_reset_complete.html'
),
name='password_reset_complete'),

go to setting
EMAIL_BACKEND = '[Link]'
EMAIL_HOST = '[Link]'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'habtamuasayto360@[Link]'
EMAIL_HOST_PASSWORD = 'mhlqxbcabxepcxht' # this password is generated on my
gmail

- There are some processes on gmail


Enhance safe browsing should on, must 2 step verification and app
password

19. Custom domain name for applicartion


- Find [Link] , but it is not free
20. Enable Https
- Go to [Link]

21. Multi language in django


- Activate virtual
py -m venv venv

- Install django
pip install django

- Create app
python [Link] startapp setting
22. Model translation
pip install django-modeltranslation
[Link]
USE_L10N = True

You might also like