web-dev-qa-db-ja.com

Django-新しいオブジェクトを保存するときにself.idを取得する方法?

モデルの1つに問題があります。画像をアップロードしていて、id(pkをデータベーステーブルに保存)したいのですが、どの時点でDjangoが_self.id_にアクセスできるようになるか)を知る必要があります。

models.py

_class BicycleAdItemKind(MPTTModel):
    def url(self, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (self.id, filename)
        return url

    def item_kind_image(self):
        return '<img align="middle" src="/media/%s" height="60px" />' % self.image
    item_kind_image.allow_tags = True     

    # Bicicleta completa, Componentes para bicicleta, Acessorios para ciclista
    n_item_kind      = models.CharField(max_length=50) 
    parent           = TreeForeignKey('self', null=True,
                                      blank=True, related_name='children')
    description      = models.TextField(null=True, blank=True)
    image            = models.ImageField(upload_to=url, null=True, blank=True)
    date_inserted    = models.DateTimeField(auto_now_add=True)
    date_last_update = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.n_item_kind

    class MPTTMeta:
        order_insertion_by = ['n_item_kind']
_

問題はurl()メソッドにあります。オブジェクトを更新するときにのみ_self.id_を取得できます。新しいオブジェクトを作成するときに_self.id_を取得しません。新しいオブジェクトを作成するときに_self.id_を取得するようにこのモデルを変更するにはどうすればよいですか?

現在のコードでは、新しいオブジェクトを作成しているとき、次のようなURLになります。

_MultimediaData/HelpAdImages/ItemKind/None/somefile.jpg
_

そして、私は次のようなものが必要です:

_MultimediaData/HelpAdImages/ItemKind/35/somefile.jpg
_

手がかりはありますか?

31
André

新しいオブジェクトの場合は、まずオブジェクトを保存してから、self.idにアクセスする必要があります。

"There's no way to tell what the value of an ID will be before you call save(), 
 because that value is calculated by your database, not by Django."

Djangoのドキュメントを確認してください https://docs.djangoproject.com/en/dev/ref/models/instances/

31
Qiang Jin

このファイル/インスタンスを2回保存する必要がある場合があります。

作成されたフラグを探すモデルでpost_save信号を使用し、インスタンスにIDがあるため、URLを更新してインスタンスを再保存します(必要に応じてファイルを移動/名前変更します)。ただし、作成された状態でのみこれを行うようにしてください。そうしないと、継続的に保存のループが発生します。保存は保存後信号を開始し、保存は保存後信号を開始します...

https://docs.djangoproject.com/en/dev/ref/signals/#post-save を参照してください

4
sbywater

注:models.AutoField(primary_key=True)属性を設定する必要があります。そうしないと、データベースは新しいIDで更新されますが、Djangoはそれを認識しません。

models.AutoField(primary_key=True)
1
Chandan Maruthi

私はこれが古いことを理解していますが、将来これに遭遇した人のために、実際にDjangoでこれを行う方法を次に示します。

def url(instance, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (instance.id, filename)
        return url
0
AnthonyMartinez