Django+ReactでのSPAでOGPタグを設定する方法

#概要
Django+ReactでのSPAでOGPタグを設定する方法を見つけたので、備忘録に。
これで実はあったよってなったら割と悲しい笑

#方法概説
Djangoには吐き出すHTMLに任意を文字列などをレンダリングする機能がある。これは応用し、特定のURLが叩かれた際、適切なOGPをレンダリングして吐き出すようにしてみた。
この方法の優れている点は外部からのアクセス者のみレンダリングするので、内部でのページ遷移ではやらないというサーバーに優しいということである。

#方法

OGP生成関数。とりあえずばーっと作ったやつなので、もうちょっと美しくできると思う。

```python
def GenOGP(title,url,image,site_name,type,dcp):
    ogp_title = "<meta property=\"og:title\" content=\""+title+"\" />\n"
    ogp_url = "<meta property=\"og:url\" content=\""+url+"\" />\n"
    ogp_type = "<meta property=\"og:type\" content=\""+ type +"\" />\n"
    ogp_dcp = "<meta property=\"og:description\" content=\""+ dcp +"\" />\n"
    ogp_site = "<meta property=\"og:site_name\" content=\""+site_name+"\" />\n"
    ogp_iamge = "<meta property=\"og:image\" content=\""+image+"\" />\n"

    sns = "<meta name=\"twitter:card\" content=\"summary\" />\n"

    twitter_title = "<meta property=\"twitter:title\" content=\""+title+"\" />\n"
    twitter_url = "<meta property=\"twitter:url\" content=\""+url+"\" />\n"
    twitter_dcp = "<meta property=\"twitter:description\" content=\""+ dcp +"\" />\n"
    twitter_site = "<meta property=\"twitter:site_name\" content=\""+site_name+"\" />\n"
    twitter_iamge = "<meta property=\"twitter:image\" content=\""+image+"\" />\n"

    twitters = twitter_title + twitter_title + twitter_dcp + twitter_site + twitter_iamge


    return ogp_title + ogp_url + ogp_type + ogp_dcp + ogp_site + ogp_iamge + sns + twitters


```

次にviews.py
私の場合とりあえず記事の部分だけOGPを埋め込むようにしたので、これを参考に他の部分を作るように。
ちなみにArticleというのが私の環境での記事モデルである。tryとかでかこっているのは単に配列の存在判定処理を書くのが面倒だっただけ。

```python
def SinglePageView(request):
    request_url = request.path
    prefix = "prefix=\"og: http://ogp.me/ns\# fb: http://ogp.me/ns/fb\# website: http://ogp.me/ns/websaite\#\""
    try:
        if request_url.split("/")[1] == "article":
            article_pk = int(request_url.split("/")[2])
            article = Article.objects.get(pk=article_pk)
            OGP_HEADER = GenOGP(article.title,"https://nullab.xyz"+request_url,"https://nullab.xyz/static/img/favicon.png","nullab","article","nullabの記事")
            return render(request,"index.html",{"SEO_HEADER":OGP_HEADER,"PREFIX":prefix})
        else:
            return render(request,"index.html")
    except:
        return render(request,"index.html")
```

つづいて

index.html

```html
{% load static %}
<!DOCTYPE html>
<html lang="ja" id="mysite">
<head {{PREFIX | safe}} >
  <title></title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" type="text/css" href="{% static "css/base.css" %}">
  <!-- Google Analytics -->
  <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

  <!-- SEO -->
  {{ SEO_HEADER | safe }}

</head>
<body>
  <div id=App>
  </div>
</body>
<script src="{% static "js/main.js" %}"></script>
</html>
```

こうすると

<img width="581" alt="screenshot 2019-10-24 20.54.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296874/b82d5d13-442f-f361-a08a-1957cc262079.png">
こんな感じにOGPみのあるアレができる。（検証はLivedoorblog）

個人的にまあまあ良い方法だと思うけど、もっと良い方法があれば教えてください。

追記
プレフィックスのエスケープ禁止令の出し忘れ修正
Twitter対応版にしてみた。
細かい修正