Skip to content

Instantly share code, notes, and snippets.

@voluntas
Last active February 26, 2019 14:46
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save voluntas/eb99619b36c056437dcdc906b5b38313 to your computer and use it in GitHub Desktop.
Save voluntas/eb99619b36c056437dcdc906b5b38313 to your computer and use it in GitHub Desktop.
Django ヤリナオシ

Django ヤリナオシ

日時

2018-04-09

@voluntas

バージョン

18.4.3

URL

https://voluntas.github.io/

突っ込みは Twitter @voluntas まで。

概要

Django でプロトタイプや自社サービスを作ることが増えてきたが、普段使っていないこともあり「これがやりたい」「あれがやりたい」というのがすぐでてこない。 自分がやりたいことを実現する方法を Django 2.0 でどうやるのかを逆引き的にまとめていきたい。

お客様向けのプロダクションで Django を書いているわけではないので間違いは多いと思う。是非そのときはツッコミをお願いしたい。

対象

  • 普段は Erlang/OTP を書いている
  • プロダクション向けに書くつもりはない
  • Django は 0.95 から知っている
  • Django 2.0 を使いたい
  • Django 1.0 の本を書いた
  • Python 3.6 を使いたい
  • Bootstrap 4.0 を初めて使う
  • React とかは使わない
    • JavaScript は最低限
    • data-* を利用する程度

つまり著者自身。

メールを送る

SendGrid を利用してメールを送る

普段 SendGrid を使っているのでそのまま利用したい。

https://github.com/sklarsa/django-sendgrid-v5

pip install django-sendgrid-v5 でインストールできる。

settings.py に EMAIL_BACKEND = "sendgrid_backend.SendgridBackend" と SENDGRID_API_KEY を設定すれば完了。

from django.core.mail import send_mail でそのまま利用できた。

https://docs.djangoproject.com/en/2.0/topics/email/

メールを Django テンプレートを利用して送りたい

Djangoで、メールを送信 - naritoブログ

from django.template.loader import get_template

mail_template = get_template('app/mail.txt')
message = mail_template.render({})

get_template を使うことで Django Template が利用可能になる。

User 拡張

Django といえば User 、つまり認証が最初からついてくるところが魅力だが、それを拡張するのは色々手が折れる。 Django 2.0 ではある程度は楽になるようだ。

ログイン / ログアウトを username ではなく email を利用するようしたい

AbstractBaseUser という機能を利用することで対応可能。

まだまとめ中

クラスベースビュー

ログインとログアウトのクラスベースビューを使いたい

auth.views に LoginView と LogoutView があるのでそれを使う。

urls.py:

from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView

urlpatterns = [
    path('login/', LoginView.as_view(template_name='app/login.html'), name='login'),
    path('logout/', LogoutView.as_view(), name='logout'),
]

認証必須のページにしたい

LoginRequredMixin というのを継承すれば良いっぽい。今のところ困っていない。

from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin

class IndexView(LoginRequiredMixin, TemplateView):
    raise_exception = True
    template_name = "app/index.html"

TemplateView に context を渡したい

get_context_data を利用する。

from django.views.generic import TemplateView

from .models import Dummy

class IndexView(LoginRequiredMixin, TemplateView):
    template_name = "app/index.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['dummy'] = Dummy.objects.get(pk=1)
        return context

モデルの保存が終わったらメールを送りたい

CreateView の場合は form_valid を利用する。

form の中身の値を利用したい場合は form.instance を利用する。

dummy.txt:

{{ dummy.name }} 様

ダミーです

views.py:

from django.views.generic.edit import CreateView
from django.core.mail import send_mail
from django.template.loader import get_template


class DummyCreateView(CreateView):
    model = Dummy

    def form_valid(self, form):
        result = super().form_valid(form)

        subject = "ダミー"
        mail_template = get_template('app/dummy.txt')
        context = {
            "dummy": form.instance,
        }
        message = mail_template.render({})
        from_email = "noreply@example.com"
        recipient_list = [
            'dummy@example.com'
        ]

        send_mail(subject, message, from_email, recipient_list)

        return result

ログインしているユーザ情報を取得したい

self.request.user でログインしている user 情報が取れる。

CreateView でサーバ側で値を追加したい

form.instance が送られ値から生成されたモデルなので、そこに値を追加する。

from django.views.generic.edit import CreateView


class DummyCreateView(CreateView):
    model = Dummy

    def form_valid(self, form):
        form.instance.text = "spam"
        return super().form_valid(form)

DetailView で pk 以外を使いたい

DetailView で pk 以外を利用する場合は get_object を利用して self.kwargs から値を利用する。

urls.py:

from django.urls import path

urlpatterns = [
    path('dummy/detail/<uuid:unique_id>/', views.DummyDetailView.as_view(), name='dummy-detail'),
]

views.py:

from django.views.generic import DetailView

class DummyDetailView(DetailView):
    template_name = 'app/dummy_detail.html'
    context_object_name = 'dummy'

    def get_object(self):
        return Dummy.objects.get(unique_id=self.kwargs['unique_id'])

get_object は CreateView や UpdateView 、 DeleteView でも利用可能。

DeleteView で削除成功時にリダイレクトする URL を指定する

削除成功時にリスト一覧を表示する。

from django.urls import reverse_lazy
from django.views.generic.edit import DeleteView

from .models import Dummy


classs DummyDeleteView(DeleteView):
    model = Dummy
    success_url = reverse_lazy('dummy-list')

DetailView で object name を変更する

これは間違っている可能性がある

そもそも User ではなく MyUser とかにすべきなのだが User にしてしまったので、 user を上書きしてしまったので object にしたかった。model 名が使われると思わず object になると思いこんでいた。

context_object_name で書き換えられる。

class UserDetailView(DetailView):
    model = User
    context_object_name = 'object'

ユーザのパスワード変更と変更完了

クラスビューが提供されていて、死ぬほど便利だった。

PasswordChangeView の success_url を PasswordChangeDoneView の URL に指定しておく必要がある。

ユーザのパスワードリセット

クラスビューが提供されている。メールもトークンも送信してくれる。

テンプレートを参考にするといい。

django-bootstrap4

zostera/django-bootstrap4: Bootstrap 4 integration with Django.

フォームをキレイにしてくれる。 {% bootstrap_form form %} の用に form を渡すだけで上手いことやってくれる。すごい便利。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment