10月3週目振り返り

今週やったこと

新規APIの設計・実装

以前実装した取得系のAPIに追加でレスポンスをフィルタリングする処理を実装しています。
フィルタリングの条件が少し複雑なので仕様を確認しつつ実装を進めています。

最初の段階でAPIを実装した時に拡張しやすい作りにすることを意識していたので、今回の改修も割とどこをどうコードを追加すれば良いかが考えやすくなって良かったです。
特にプライベートメソッドで処理の責務を分けることを意識していたので、今回の改修で変更を加えるのは特定のプライベートメソッドのみになり、テストも書きやすい状態にできそうです。

他のチームメンバーのプルリクレビュー

チーム内のプルリクエストにも積極的にコメントを入れて議論に参加しました。
今の現場で半年ほど働いているのでコンテキストもだいぶ理解できているので、今後も積極的に参加していきたいと思います。

今週学んだこと

Djangoのモデルにユニーク制約をつける方法

djangobrothers.com Djangoのモデルでclass Meta内にmodels.UniqueConstraintを指定してユニーク制約をつけることができることを知りました。
まだまだDjangoフレームワークの機能で知らないことが多いので新しい発見があると楽しいです。

class Metaの公式ドキュメントでの説明は以下だと思います。

docs.djangoproject.com

気になったのでDjangoGitHubリポジトリも読んでみるとUniqueConstraintのクラスは以下で実装されていそうでした。

github.com

__init__は以下のようになっており、バリデーションが多く含まれているようです。

class UniqueConstraint(BaseConstraint):
    def __init__(
        self,
        *expressions,
        fields=(),
        name=None,
        condition=None,
        deferrable=None,
        include=None,
        opclasses=(),
        nulls_distinct=None,
        violation_error_code=None,
        violation_error_message=None,
    ):
        if not name:
            raise ValueError("A unique constraint must be named.")
        if not expressions and not fields:
            raise ValueError(
                "At least one field or expression is required to define a "
                "unique constraint."
            )
        if expressions and fields:
            raise ValueError(
                "UniqueConstraint.fields and expressions are mutually exclusive."
            )
        if not isinstance(condition, (NoneType, Q)):
            raise ValueError("UniqueConstraint.condition must be a Q instance.")
        if condition and deferrable:
            raise ValueError("UniqueConstraint with conditions cannot be deferred.")
        if include and deferrable:
            raise ValueError("UniqueConstraint with include fields cannot be deferred.")
        if opclasses and deferrable:
            raise ValueError("UniqueConstraint with opclasses cannot be deferred.")
        if expressions and deferrable:
            raise ValueError("UniqueConstraint with expressions cannot be deferred.")
        if expressions and opclasses:
            raise ValueError(
                "UniqueConstraint.opclasses cannot be used with expressions. "
                "Use django.contrib.postgres.indexes.OpClass() instead."
            )
        if not isinstance(deferrable, (NoneType, Deferrable)):
            raise TypeError(
                "UniqueConstraint.deferrable must be a Deferrable instance."
            )
        if not isinstance(include, (NoneType, list, tuple)):
            raise TypeError("UniqueConstraint.include must be a list or tuple.")
        if not isinstance(opclasses, (list, tuple)):
            raise TypeError("UniqueConstraint.opclasses must be a list or tuple.")
        if not isinstance(nulls_distinct, (NoneType, bool)):
            raise TypeError("UniqueConstraint.nulls_distinct must be a bool.")
        if opclasses and len(fields) != len(opclasses):
            raise ValueError(
                "UniqueConstraint.fields and UniqueConstraint.opclasses must "
                "have the same number of elements."
            )
        self.fields = tuple(fields)
        self.condition = condition
        self.deferrable = deferrable
        self.include = tuple(include) if include else ()
        self.opclasses = opclasses
        self.nulls_distinct = nulls_distinct
        self.expressions = tuple(
            F(expression) if isinstance(expression, str) else expression
            for expression in expressions
        )
        super().__init__(
            name=name,
            violation_error_code=violation_error_code,
            violation_error_message=violation_error_message,
        )

面白かった記事など

AI周りの記事は定期的にチェックしていて、以下も結構おもしろかったです。

xtech.nikkei.com