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)
    ...

我 100% 确定我的 field_m2m 和 field_fk 不是空的,而且同样重要的是:存在对应于 EXISTING 标签的实例。我还有其他功能很好地涵盖了这部分。我还尝试对字符串 ( Tag.objects.get(name="mystring")) 进行硬编码,以确保 101% 确定。

然而,没有通过管理面板分配标签。我试图通过 shell 中的步骤,它在那里工作。

>>> 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 回答
0

多亏了这个提示才弄清楚:https
://stackoverflow.com/a/6200451/1344854 模型 save() 方法保持默认。首先,我将标签绑定到我的 FkModel 和 M2mModel 实例。其余工作在 ModelAdmin 中完成。

# models.py
class FkModel(models.Model):
    name = models.CharField(max_length=255, unique=True)
    tag = models.ForeignKey(Tag, blank=True, null=True, related_name='fk')
    ...

class M2mModel(models.Model):
    name = models.CharField(max_length=255, unique=True)
    tag = models.ForeignKey(Tag, blank=True, null=True, related_name='m2m')
    ...

# admin.py
class MyModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        form.save() # as I learned, without saving at this point, obj.field_m2m.all() will be empty
        tags = []
        if obj.field_m2m.all():
            tags += [m2m.tag for m2m in obj.field_m2m.all()]
        if obj.field_fk:
            tags += [obj.field_fk.tag]
        form.cleaned_data['tags'] = tags
        super(MyModelAdmin, self).save_model(request, obj, form, change)
于 2013-06-13T16:44:37.900 回答