5

オブジェクトが一意であることを確認し、ユーザーがそれを保存しようとしたときにエラーをスローしたい (たとえば、管理者を介して) そうでない場合は? 一意とは、オブジェクトの属性の一部が他のオブジェクトの値と同じ値を保持している可能性があることを意味しますが、それらがすべて別のオブジェクトの値と同一であるとは限りません。

私が間違っていなければ、私はこれを次のように行うことができます:

class Animal(models.Model):
    common_name = models.CharField(max_length=150)
    latin_name = models.CharField(max_length=150)
    class Meta:
        unique_together = ("common_name", "latin_name")

ただし、モデルをリファクタリングするたびに (たとえば、新しいフィールドを追加したり、既存のフィールドの名前を変更したりするため)、unique_togetherに割り当てられた括弧内のフィールドのリストも編集する必要があります。単純なモデルであれば問題ありませんが、大規模なモデルではリファクタリングが非常に面倒になります。

unique_together括弧内にフィールド名のリストを繰り返し入力する必要がないようにするにはどうすればよいですか? モデルのフィールドのリストを変数に渡し、代わりにその変数をunique_togetherに割り当てる方法はありますか?

4

1 に答える 1

4

モデルのリファクタリングはかなりコストがかかります。

  • フィールド名はオブジェクトのプロパティに対応するため、モデルを使用してすべてのコードを変更する必要があります
  • Djangoはこれを行うことができないため、データベースを手動で変更する必要があります(少なくとも、前回Djangoで作業したときに使用したバージョンではできませんでした)

したがって、モデル メタ クラスの一意のフィールド名のリストを更新することは、心配する必要のない問題だと思います。

編集: 本当にこれをやりたいと思っていて、すべてのフィールドが「一緒に一意」でなければならない場合は、freenode の担当者が正しいので、カスタム メタクラスを作成する必要があります。これは非常に複雑でエラーが発生しやすく、コードが Django の将来のリリースと互換性がなくなる可能性があります。

Django の ORM の「魔法」は、ジェネリック基本クラスのメタクラスModelBase( ) によって制御されます。このクラスは、すべてのフィールドとメタ情報を含むクラス定義を取得し、後でコードで使用するクラスを構築します。django.db.models.base.ModelBaseModel

目標を達成するためのレシピは次のとおりです。

  1. サブクラスModelBase化して、独自のメタクラスを使用します。
  2. メソッドをオーバーライドする__new__(cls, name, bases, dict)
  3. 検査してメンバー ( ) とすべてのフィールド メンバーdictを収集しますMetadict["Meta"]
  4. meta.unique_together集めたフィールドの名前に基づいて設定します。
  5. スーパー実装を呼び出す ( ModelBase.__new__)
  6. マジック メンバーを使用して、独自のすべてのモデルにカスタム メタクラスを使用します(または、メタクラスを拡張してオーバーライド__metaclass__ = MyMetaclassする抽象基本クラスを派生させます)。Model
于 2009-09-07T14:39:37.417 に答える