utamaro’s blog

誰かの役に立つ情報を発信するブログ

Djangoのサンプルを覗いて使い方を勉強してみたときのメモ

django-realworld-example-appを参考にする

このプロジェクトは一番最初に参考にしたものです。

Djangoのバージョンが1.10.0と古い(記事を書いている段階での最新は2.1.5が最新)です。

https://github.com/gothinkster/django-realworld-example-app

このプロジェクトで学べること

  • ForeignKeyフィールドの作り方
author = models.ForeignKey(
    'profiles.Profile', on_delete=models.CASCADE, related_name='articles'
)
  • serializerクラスの使い方
    • method_nameというのを知りました。
    • SerializerMethodFieldを使ったget_xxxの方法を知りました。
updatedAt = serializers.SerializerMethodField(method_name='get_updated_at')
favorited = serializers.SerializerMethodField()

def get_favorited(self, instance):
    request = self.context.get('request', None)

    if request is None:
        return False

    if not request.user.is_authenticated():
        return False

    return request.user.profile.has_favorited(instance)

# ↓が実行されます
# def has_favorited(self, article):
    # """Returns True if we have favorited `article`; else False."""
    # return self.favorites.filter(pk=article.pk).exists()
  • models.pyの作り方
    • 多対多のリレーションの書き方. xxx_by
    • orderingを指定したデフォルトのソード方法
favorites = models.ManyToManyField(
    'articles.Article',
    related_name='favorited_by'
)
ordering = ['-created_at', '-updated_at']
  • urls.pyの階層構造
url(r'^api/', include('conduit.apps.profiles.urls', namespace='profiles')),
  • jsonレスポンスの拡張方法
    • ページネーションを想定したレスポンス
class ConduitJSONRenderer(JSONRenderer):
    charset = 'utf-8'
    object_label = 'object'
    pagination_object_label = 'objects'
    pagination_object_count = 'count'

    def render(self, data, media_type=None, renderer_context=None):
        if data.get('results', None) is not None:
            return json.dumps({
                self.pagination_object_label: data['results'],
                self.pagination_count_label: data['count']
            })

        # If the view throws an error (such as the user can't be authenticated
        # or something similar), `data` will contain an `errors` key. We want
        # the default JSONRenderer to handle rendering errors, so we need to
        # check for this case.
        elif data.get('errors', None) is not None:
            return super(ConduitJSONRenderer, self).render(data)

        else:
            return json.dumps({
                self.object_label: data
            })