【问题标题】:how to set default values for manytomanyfield如何为 manytomanyfield 设置默认值
【发布时间】:2012-05-02 22:48:50
【问题描述】:

有没有办法解决“实例需要有一个主键值才能使用多对多关系”错误?

我有一个包含多个字段的模型,包括与另一个模型的多对多关系。当我创建模型的新实例时,我有一个函数可以在这些字段上设置默认值。我在处理 HTTP GET 时在视图中执行此操作。 m2m 字段使用表单集呈现。

下面是一些描述这种情况的伪代码:

class MyRelatedModel(models.Model):
  name = models.CharField(max_length=100,blank=True)

class MyModel(models.Model):
  name = models.CharField(max_length=100,blank=True)
  relatedModels = models.ManyToManyField("MyRelatedModel")

  def initialize(self):
    self.name = "my default name"
    # this bit doesn't really matter...
    # just assume I am creating a new set of RelatedModels that I want to associate with my this new MyModel...
    newRelatedModels = []
    for name in ["related model 1", "related model 2", "related model 3"]:
      relatedModel = MyRelatedModel(name=name)
      relatedModel.save()
      newRelatedModels.append(relatedModel.id)
    self.relatedModels = newRelatedModels # this is invalid!

def MyView(request):
  if request.method == 'GET':
    model = MyModel()
    model.initialize()
    form = MyForm(instance=model)
  return render_to_response("my_template.html", {"form" : form}, context_instance=RequestContext(request))

有什么建议吗?

我怀疑我可能需要在表单端而不是模型端处理这个问题,但这也让我感到困惑。

【问题讨论】:

  • 您需要先保存模型,然后才能与其他模型进行关联。类似 self.save()

标签: django django-models django-forms many-to-many


【解决方案1】:

对于 1.3.1 中对我有用的表单:

是类似的东西,inital中的manytomany

使用硬编码 ID:

def MyView(request):
    if request.method == 'GET':
        model   = MyModel( name = "my default name")
        initial = { 'relatedModels': [1,] } # assuming you knew the id and wanted to hardcode it
        form = MyForm( instance=model, initial=initial )
        return render_to_response("my_template.html", {"form" : form}, context_instance=RequestContext(request))

使用查询按名称填充:

def MyView(request):
    if request.method == 'GET':
        model   = MyModel( name = "my default name")
        initial = { 'relatedModels':  [ o.pk for o in list(MyRelatedModel.objects.filter( name__in=("related model 1", "related model 2", "related model 3")))], } 
        form = MyForm( instance=model, initial=initial )
        return render_to_response("my_template.html", {"form" : form}, context_instance=RequestContext(request))

【讨论】:

    【解决方案2】:
    for name in ["related model 1", "related model 2", "related model 3"]:
        relatedModel = MyRelatedModel(name=name)
        relatedModel.save()
        self.relatedModels.add(relatedModel)
    

    或者:

    newRelatedModels = []
    for name in ["related model 1", "related model 2", "related model 3"]:
        relatedModel = MyRelatedModel(name=name)
        relatedModel.save()
        newRelatedModels.append(relatedModel)
    self.relatedModels.add(*newRelatedModels)
    

    这应该也可以:

    self.relatedModels = newRelatedModels
    

    【讨论】:

    • 我认为问题在于self 在保存self 之前对pk 没有价值。这意味着问题不是来自相关模式保存,而是在进行 pk 之前将模型分配给自己时出现。
    • 当然,你应该在调用initialize之前保存model对象
    猜你喜欢
    • 2021-01-22
    • 2014-03-27
    • 2017-11-12
    • 2011-08-31
    • 2020-12-14
    • 2017-12-26
    • 1970-01-01
    • 2020-11-25
    • 2012-08-19
    相关资源
    最近更新 更多