---
tags: Python Web
source: Django 2.0 для начинающих, Глава 13-15, с.310
---
# Тема 11. Разрешения и авторизация. Комментарии
https://github.com/roman-yatsenko/django-topics/tree/main/news
## Создание страницы
### `articles\views.py`
```python=
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView # update
from django.urls import reverse_lazy
from . import models
# new
class ArticleCreateView(CreateView):
model = models.Article
template_name = 'article_new.html'
fields = ['title', 'body', 'author']
```
### `articles\urls.py`
```python=5
urlpatterns = [
path('', views.ArticleListView.as_view(), name='article_list'),
path('<int:pk>/edit/',
views.ArticleUpdateView.as_view(), name='article_edit'),
path('<int:pk>/',
views.ArticleDetailView.as_view(), name='article_detail'),
path('<int:pk>/delete/',
views.ArticleDeleteView.as_view(), name='article_delete'),
path('new/', views.ArticleCreateView.as_view(), name='article_new'), # new
]
```
```shell
touch templates/article_new.html
```
### `templates\article_new.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>New article</h1>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-success ml-2" type="submit">Save</button>
</form>
{% endblock %}
```
### `templates\base.html`
```htmlmixed=15
<a class="navbar-brand" href="{% url 'home' %}">Newspaper</a>
{% if user.is_authenticated %}
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a href="{% url 'article_new' %}">+ New</a></li>
</ul>
{% endif %}
```
```shell
python manage.py runserver
```
:link: https://getbootstrap.com/docs/4.0/components/jumbotron/
### `templates\home.html`
```htmlmixed=5
{% block content %}
<div class="jumbotron">
<h1 class="display-4">Newspaper app</h1>
<p class="lead">A Newspaper website built with Django.</p>
<p class="lead">
<a class="btn btn-primary btn-lg" href="{% url 'article_list' %}"
role="button">View All Articles</a>
</p>
</div>
{% endblock %}
```
## Улучшение CreateView
### `articles\views.py`
```python=8
class ArticleCreateView(CreateView):
model = models.Article
template_name = 'article_new.html'
fields = ['title', 'body', ] # update
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
```
## Авторизация
Log out and go to http://127.0.0.1:8000/articles/new/
### `articles\views.py`
```python=4
from django.contrib.auth.mixins import LoginRequiredMixin # new
from . import models
class ArticleCreateView(LoginRequiredMixin, CreateView): # update
```
:link: http://127.0.0.1:8000/articles/new/
```python=10
model = models.Article
template_name = 'article_new.html'
fields = ['title', 'body', ]
login_url = 'login' # new
```
## Обновление views
### `articles\views.py`
```python=20
class ArticleListView(LoginRequiredMixin, ListView): # update
model = models.Article
template_name = 'article_list.html'
login_url = 'login' # new
class ArticleDetailView(LoginRequiredMixin, DetailView): # update
model = models.Article
template_name = 'article_detail.html'
login_url = 'login' # new
class ArticleUpdateView(LoginRequiredMixin, UpdateView): # update
model = models.Article
fields = ['title', 'body', ]
template_name = 'article_edit.html'
login_url = 'login' # new
class ArticleDeleteView(LoginRequiredMixin, DeleteView): # update
model = models.Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
login_url = 'login' # new
```
## Комментарии
### `articles\models.py`
```python=22
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
comment = models.CharField(max_length=140)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.comment
def get_absolute_url(self):
return reverse('article_list')
```
```shell
python manage.py makemigrations articles
python manage.py migrate
```
### `articles\admin.py`
```python=6
admin.site.register(models.Comment)
```
:link: http://127.0.0.1:8000/admin/
Add comment not from admin user
### `articles\admin.py`
```python=6
class CommentInline(admin.StackedInline): # new
model = models.Comment
class ArticleAdmin(admin.ModelAdmin): # new
inlines = [
CommentInline,
]
admin.site.register(models.Article, ArticleAdmin) # update
```
Reload admin page for article with comment
```python=6
class CommentInline(admin.TabularInline): # update
```
## Шаблон для комментариев
### `articles\models.py`
```python=22
class Comment(models.Model):
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name='comments'
)
```
```shell
python manage.py makemigrations articles
python manage.py migrate
python manage.py runserver
```
### `templates\article_list.html`
```htmlmixed=16
<div class="card-body">
<p>{{ article.body }}</p>
<a href="{% url 'article_edit' article.pk %}">Edit</a> |
<a href="{% url 'article_delete' article.pk %}">Delete</a>
</div>
<div class="card-footer">
{% for comment in article.comments.all %}
<p>
<span class="font-weight-bold">{{ comment.author }} · </span>
{{ comment }}
</p>
{% endfor %}
</div>
```
---
(c) Яценко Р.Н., 2021
[Учебный центр компьютерных технологий "Кит"](http://kit.kh.ua/)
<img src="https://i.imgur.com/Kh901c1.png" style="width: 150px; position: fixed; top: 100px; right: 10px; border: 0; box-shadow: none;">