web-dev-qa-db-ja.com

Django 1.6への移行でget_profile()を削除します

Django 1.5およびカスタムユーザーモデルの導入により、_AUTH_PROFILE_MODULE_は非推奨になりました。既存のDjangoアプリケーションでは、Userモデルを使用し、私もProfileへの外部キーを持つUserモデルがあり、ユーザーに関するその他の情報をプロファイルに格納します。現在_AUTH_PROFILE_MODULE_を使用しており、これは「app.profile」に設定されています。
明らかに、私のコードは多くのuser.get_profile()を実行する傾向があり、これをなくす必要があります。

これで、新しいカスタムユーザーモデルを作成できます(プロファイルモデルをUserに拡張するだけです)が、現在ユーザーへの外部キーを持っている他のすべての場所でも変更する必要があります...したがって、これは私のライブサービスでの大規模な移行。

モデルを移行せずに、どこかでget_profile())のようなものでmy_user.userprofile_set.all()[0]関数を作成/オーバーライドする方法はありますか?

この道を進み、アイデアや経験を共有できる人はいますか?

もし私が今このサービスをどこでやり直すのか-明らかにこのようには行かないでしょうが、中規模のライブプロダクションシステムで私はショートカットを開いています:-)

25
Jens Lundstrom

組み込みのUserに関連するプロファイルモデルを使用することは、追加のユーザー情報を格納するための完全に正当な構成です(多くの場合推奨されます)。組み込みのDjango 1対1の構文がここでクリーンかつエレガントに機能することを考えると、現在非推奨になっているAUTH_PROFILE_MODULEおよびget_profile()のものは不要になりました。

すでに使用している場合、古い使用法からの移行は実際には簡単ですプロファイルモデルでOneToOneFieldからUserを使用するこれは、 以前にプロファイルモジュールを設定することをお勧めした方法ですget_profileは非推奨になりました

class UserProfile(models.Model):
    user = OneToOneField(User, related_name="profile")
    # add profile fields here, e.g.,
    nickname = CharField(...)

# usage: no get_profile() needed. Just standard 1-to-1 reverse syntax!
nickname = request.user.profile.nickname  

これを可能にするOneToOneFieldの構文上の魔法に慣れていない場合は、 here を参照してください。最終的には、get_profile()profileまたはrelated_nameに置き換えるだけで済みます(上記の場合の自動関連名はuser_profileになります)。標準Django逆1-1構文は実際にはget_profile()よりも優れています!

ForeignKeyをOneToOneFieldに変更します

しかし、これではあなたの質問に完全に答えることはできないと思います。プロファイルモジュールでForeignKeyではなくUserからOneToOneを使用したことを示していますが、これは問題ありませんが、フォローアップコメントに記載されているように、ForeignKeyのままにしておくと構文は単純ではありません。
実際にはForeignKeyを一意の外部キー(基本的に1対1)として使用していると仮定すると、 DB内のOneToOneFieldは、unique=True制約のあるForeignKeyフィールドにすぎません。 、コード内でForeignKeyフィールドをOneToOneFieldに変更できます。実際にデータベースを大幅に移行したり、データを失ったりする必要はありません。

南への移住への対処

移行にSouthを使用している場合、前のセクションからのコード変更により、Southが古いフィールドを削除して作成するのを混乱させる可能性があります。 schemamigration --autoを実行する場合は新しいものなので、正しく実行するには移行を手動で編集する必要がある場合があります。 1つのアプローチは、スキーママイグレーションを作成してから、forwardsメソッドとbackwardsメソッドを空白にして、実際には何も実行しようとしないようにすることですが、それでもモデルをOneToOneFieldとして適切にフリーズします。次に、物事を完璧に実行したい場合は、対応するデータベースの外部キー列にも一意性制約を追加する必要があります。これは、SQLを使用して手動で行うか、Southを介して行うことができます(移行方法を手動で編集するか、ForeignKeyunique=Trueを設定し、最初のSouth移行を作成してから、OneToOneFieldに切り替えて、2番目の移行を行い、フォワード/バックワードメソッド)。

67
Ben Roberts