# 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.
我想我应该在进行上述任务之前保存模型实例,对吧?我该如何一次完成所有工作?
答案 0 :(得分:1)
在我保存任何关系之前,似乎必须将您的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))
希望这有帮助!
答案 1 :(得分: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)