DjangoとNewsAPIを使って携帯大手3社のニュースをそれぞれ取得する

#はじめに
プログラミング初心者なので暖かい目でこの記事を見ていただけると幸いです。
#環境
Windows10
Python 3.7.6
newsapi-python 0.2.6
Django 3.0.6
DateTime 4.3

また作成時のディレクトリの名前は以下の通りになります。

```
sample_news
├─news
├─sample_news
├─static
└─manage.py
```
#NewsAPIの導入
[NewsAPIのサイト](https://newsapi.org/)に行きメールアドレスを入力してAPIキーを取得し、そのAPIキーはメモしておいてください。
その後pipでNewsAPIのライブラリをインストールしてください。

```
pip install newsapi-python
```

sample_newsにあるsetting.pyに以下のコードを追加してNewsAPIを使えるようにしてください。
api_keyは自分のメモしたキーを入力して下さい。

```python:setting.py
from newsapi import NewsApiClient

newsapi=NewsApiClient(api_key='xxxxxxxxxxxxxxxxxxxxxx')

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'news.apps.NewsConfig',
    'newsapi',
]
```
これでNewsAPIが使えるようになりました。

#ニュースアプリの作成
##ルーティングの設定
ルーティングを設定するためにsample_newsのurls.pyに以下のコードを追加してください。

```python:sample_news/urls.py
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('news.urls')),
]
```
次にnewsにurls.pyを作成し以下のコードを入力しました。

```python:news/urls.py
from django.urls import path
from.import views

app_name = 'news'
urlpatterns = [
    path('', views.IndexView.as_view(), name="index"),
    path('docomo/',views.DocomoView.as_view(),name="docomo"),
    path('au/',views.AuView.as_view(),name="au"),
    path('softbank/',views.SoftbankView.as_view(),name="softbank")
]
```
##NewsAPIでニュースを取得する
NewsAPIではトップニュースを取得する方法と過去の一定の期間のニュースを取得する方法の2つがあります。

トップニュースを取得した場合はニュースがなかった場合何も表示されなかったので一定期間のニュースを取得する方法を採用しました。NewsAPIは課金しなかった場合30日前までのニュースを取得できます。

今回はキーワード、期間、表示する順番、ニュースの数を指定しました。
ほかにもタイトルのキーワード、ソース、ドメイン、言語（日本語は不可）などがあります。

```python:news/views.py
from django.views import generic
from newsapi import NewsApiClient
from datetime import datetime, date, timedelta

class IndexView(generic.TemplateView):
    template_name = "index.html"

class DocomoView(generic.TemplateView):
    template_name = "docomo.html"

    def get_context_data(self, **kwargs):
        context=super().get_context_data(**kwargs)
        today = date.today()
        monthago = today-timedelta(days=30)
        newsapi = NewsApiClient(api_key='xxxxxxxxxxxxxxxxxxxxxx')
        context['all_article']=newsapi.get_everything(q='ドコモ',
                                                      from_param=monthago,
                                                      to=today,
                                                      sort_by='publishedAt',
                                                      page_size=40)
        return context

class AuView(generic.TemplateView):
    template_name = "au.html"

    def get_context_data(self, **kwargs):
        context=super().get_context_data(**kwargs)
        today = date.today()
        monthago = today-timedelta(days=30)
        newsapi = NewsApiClient(api_key='xxxxxxxxxxxxxxxxxxxxxx')
        context['all_article']=newsapi.get_everything(q='KDDI',
                                                      from_param=monthago,
                                                      to=today,
                                                      sort_by='publishedAt',
                                                      page_size=40)
        return context

class SoftbankView(generic.TemplateView):
    template_name = "softbank.html"

    def get_context_data(self, **kwargs):
        context=super().get_context_data(**kwargs)
        today = date.today()
        monthago = today-timedelta(days=30)
        newsapi = NewsApiClient(api_key='xxxxxxxxxxxxxxxxxxxxxx')
        context['all_article']=newsapi.get_everything(q='ソフトバンク',
                                                      from_param=monthago,
                                                      to=today,
                                                      sort_by='publishedAt',
                                                      page_size=40)
        return context
```
これでニュースを取得するプログラムは完成したのであとはコーティングをするだけです。

##取得したニュースを表示する
今回はトップページ(index.html)、ドコモのニュースを表示するページ(docomo.html)、auのニュースを表示するページ(au.html)、ソフトバンクのニュース(softbank.html)を表示するページの4つのページと、各ページに共通する部分(base.html)の５つのhtmlファイルを作成しました。

```
templates
├─au.html
├─base.html
├─docomo.html
├─index.html
└─softbank.html
```

ドコモのニュースを表示するページは以下の通りです。

今回はタイトルとurlとニュースの画像を取得して表示するようにしました。

```html:docomo.html
{% extends 'base.html' %}
{% block title %}Sample_News | SOFTBANK{% endblock %}
{% block contents %}
<div class="grid">
{% for context in all_article.articles %}
<div class="news">
    <div class="news-wrapper">
        <img class="news-img" src="{{ context.urlToImage }}" alt="">
        <a class="news-title" href="{{ context.url }}">{{ context.title }}</a>
    </div>
</div>
{% endfor %}
</div>
{% endblock %}
```
このような感じでauとソフトバンクのhtmlファイルも記述します。

最後にCSSでのコーディングをして完成です。

topページ
![newstop.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617662/50d2e650-7741-b1cb-2f30-e4f227335294.png)

ドコモのニュースのページ
![docomo.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617662/5cab68f9-7d5c-865e-4e65-c571ee0b7c1c.png)

#まとめ
今回はdjangoを勉強した後に初めて作ったwebアプリなので参考書などをたくさん活用して作りました。勉強した後に復讐のために自分でwebアプリを作るとより理解が深められると自分で感じることができました。

検索の単語をドコモはドコモ、auはau、ソフトバンクはソフトバンクでやったのですが、ドコモはドコモのニュースのみが出力されたのですが、auは海外のニュースが、ソフトバンクは野球のニュースが出力されたのでそこを改善していきたいと思います。

また記事を書くのも初めてなので至らぬことがあれば教えていただけるとありがたいです。
#参考
- [動かして学ぶ！Python Django開発入門](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
- [Python 3.7.7 documentation](https://docs.python.org/3.7/)
- [NewsAPI](https://newsapi.org/)