---
tags: Python Web
source: Django 2.0 для начинающих, Глава 13, с.257
---
# Тема 10. Приложение Newspaper
https://github.com/roman-yatsenko/django-topics/tree/main/news
## Приложение Articles
```shell
python manage.py startapp articles
```
### `news_project\settings.py`
```python=33
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 3rd Party
'crispy_forms',
# Local
'users',
'pages',
'articles' # new
]
```
```python=114
LANGUAGE_CODE = 'ru'
TIME_ZONE = 'Europe/Kiev'
```
### `articles\models.py`
```python=
from django.conf import settings
from django.db import models
from django.urls import reverse
class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
```
```shell
python manage.py makemigrations articles
python manage.py migrate
```
### `articles\admin.py`
```python
from django.contrib import admin
from . import models
admin.site.register(models.Article)
```
```shell
python manage.py runserver
```
:link: http://127.0.0.1:8000/admin/
:arrow_right: *Добавьте три статьи*
## URLs и Views
### `news_project\urls.py`
```python=19
urlpatterns = [
path('', include('pages.urls')),
path('articles/', include('articles.urls')), # new
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
path('users/', include('django.contrib.auth.urls')),
]
```
```shell
touch articles/urls.py
```
### `articles\urls.py`
```python=
from django.urls import path
from . import views
urlpatterns = [
path('', views.ArticleListView.as_view(), name='article_list'),
]
```
### `articles\views.py`
```python
from django.views.generic import ListView
from . import models
class ArticleListView(ListView):
model = models.Article
template_name = 'article_list.html'
```
```shell
touch templates/article_list.html
```
### `templates\article_list.html`
```htmlmixed=
{% extends 'base.html' %}
{% block title %}Articles{% endblock %}
{% block content %}
{% for article in object_list %}
<div class="card">
<div class="card-header">
<span class="font-weight-bold">{{ article.title }}</span>
·
<span class="text-muted">
by {{ article.author }} | {{ article.date }}
</span>
</div>
<div class="card-body">
{{ article.body }}
</div>
<div class="card-footer text-center text-muted">
<a href="#">Edit</a> | <a href="#">Delete</a>
</div>
</div>
<br />
{% endfor %}
{% endblock content %}
```
```shell
python manage.py runserver
```
:link: http://127.0.0.1:8000/articles/
## Редактирование/Удаление
```python=5
urlpatterns = [
path('', views.ArticleListView.as_view(), name='article_list'),
path('<int:pk>/edit/',
views.ArticleUpdateView.as_view(), name='article_edit'), # new
path('<int:pk>/',
views.ArticleDetailView.as_view(), name='article_detail'), # new
path('<int:pk>/delete/',
views.ArticleDeleteView.as_view(), name='article_delete'), # new
]
```
### `articles\views.py`
```python
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView
from django.urls import reverse_lazy
from . import models
class ArticleListView(ListView):
model = models.Article
template_name = 'article_list.html'
class ArticleDetailView(DetailView):
model = models.Article
template_name = 'article_detail.html'
class ArticleUpdateView(UpdateView):
model = models.Article
fields = ['title', 'body', ]
template_name = 'article_edit.html'
class ArticleDeleteView(DeleteView):
model = models.Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
```
```shell
touch templates/article_{detail,edit,delete}.html
```
### `templates\article_detail.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<div class="article-entry">
<h2>{{ object.title }}</h2>
<p>by {{ object.author }} | {{ object.date }}</p>
<p>{{ object.body }}</p>
</div>
<p>
<a href="{% url 'article_edit' article.pk %}">Edit</a> |
<a href="{% url 'article_delete' article.pk %}">Delete</a>
</p>
<p>Back to <a href="{% url 'article_list' %}">All Articles</a>.</p>
{% endblock content %}
```
### `templates\article_edit.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>Edit</h1>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-info ml-2" type="submit">Update</button>
</form>
{% endblock %}
```
### `templates\article_delete.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>Delete</h1>
<form action="" method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ article.title }}"?</p>
<button class="btn btn-danger ml-2" type="submit">Confirm</button>
</form>
{% endblock %}
```
### `templates\article_list.html`
```htmlmixed=20
<a href="{% url 'article_edit' article.pk %}">Edit</a> |
<a href="{% url 'article_delete' article.pk %}">Delete</a>
```
```shell
python manage.py runserver
```
:link: http://127.0.0.1:8000/articles/
---
(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;">