0

再び壁に頭をぶつける。他の既知のフィールドを使用してタグを追加しようとしています

# models.py
class MyModel(models.Model):
    ...
    tags = models.ManyToManyField(Tag, blank=True)
    field_m2m = models.ManyToManyField('M2mModel', blank=True)
    field_fk = models.ForeignKey('FkModel', blank=True, null=True)
    ...
    def save(self, *args, **kwargs):
        for inst in self.field_m2m.all():
            self.tags.add(Tag.objects.get(name=inst.name))
        self.tags.add(Tag.objects.get(name=self.field_fk.name))
        super(MyModel, self).save(*args, **kwargs)

class FkModel(models.Model):
    name = models.CharField(max_length=255, unique=True)
    ...

class M2mModel(models.Model):
    name = models.CharField(max_length=255, unique=True)
    ...

field_m2m と field_fk が空ではないことは 100% 確信しています。重要なことは、既存のタグに対応するインスタンスがあることです。この部分をうまくカバーする他の機能があります。また、文字列 ( Tag.objects.get(name="mystring")) を 101% 確実にハードコーディングしてみました。

まだ、管理パネルからタグが割り当てられていません。シェルで手順を実行しようとしましたが、そこで動作します。

>>> m = MyModel.objects.get(name='something')
>>> t = Tag.objects.get(name='sometag')
>>> m.tags.add(t)
>>> m.tags.all()
[<Tag: sometag>]

save() メソッドから動作させるには?

また、モデル インスタンスが初めて作成されるまで、トレースバックは次のように不平を言っています。"<MyModel: Something>" needs to have a value for field "mymodel" before this many-to-many relationship can be used.

前述の割り当てを行う前に、モデル インスタンスを保存する必要があると思いますよね? どうすればすべてを一度に行うことができますか?

4

2 に答える 2

2

関係を保存する前に、MyModelインスタンスをデータベースに保存する必要があるようです。リレーションシップには MyModel の ID が必要なので、これは理にかなっています。saveしたがって、次のようにメソッドの順序を変更できます。

def save(self, *args, **kwargs):
    # notice that super class save go first.
    super(MyModel, self).save(*args, **kwargs)
    # also this cicle doesn't make sense since self is a newly
    # created instance so it won't have anythin in field_m2m.all()
    for inst in self.field_m2m.all():
        self.tags.add(Tag.objects.get(name=inst.name))
    # this should work ok if get returns any tag.
    self.tags.add(Tag.objects.get(name=self.field_fk.name))

お役に立てれば!

于 2013-06-05T19:27:54.303 に答える