---
# System prepended metadata

title: Тема 10. Приложение Newspaper
tags: [Python Web]

---

---
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> 
      &middot;
      <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;">
