在可选添加额外字段时更改模型表单的顺序?

时间:2014-10-01 14:17:53

标签: python django forms django-forms django-1.7

我有这个型号:

class Server(models.Model):
  user = models.ForeignKey('auth.User',related_name="servers")
  is_shared = models.BooleanField(default=True, editable=False)
  name = models.CharField(max_length=255, default='testserver')
  hostname = models.CharField(max_length=255, default='localhost')
  username = models.CharField(max_length=255, default='user')
  password = models.CharField(max_length=255, default='pass')
  path = models.CharField(max_length=255, default='/')
  mkdir = models.BooleanField(default=False)
  port = models.IntegerField(max_length=4, default=21)
  quirky = models.BooleanField(default=False)
  class Meta:
    unique_together = ('user', 'name',)
  def __unicode__(self):
    return self.name
  class Meta:
    verbose_name_plural = "Server"

我正在创建一个模型表单:

class ServerForm(ModelForm):
  delete = forms.BooleanField(required=False)

  def __init__(self, *args, **kwargs):
    super(ServerForm, self).__init__(*args,**kwargs)
    if (self.instance.pk is None):
        self.fields['name'] = forms.CharField(max_length=255, required=True)
        del self.fields['delete']
  class Meta:
    model = Server
    exclude = ["user","name"]

关键是用户可能不会更改现有服务器对象的名称字段,但如果表单中没有实例,我希望用户指定名称。换句话说:用户应该提供名称,但不要在以后更改。

当我使用此代码时,名称最终位于底部,但它应位于顶部。在早期的django版本中,插入可以解决这个问题,但是自从进入django 1.7以来,它不再起作用了。

然后我在这里读到: How can I order fields in Django ModelForm?

...使用元类中的fields值。但现在我遇到的问题是,字段列表有时应包含“名称”,有时则不包括“名称”。取决于是否有实例。但是从Meta类我不能使用self.instance来检查。再次列出所有字段只是为了改变顺序似乎有点烦人。

如何更改模型表单字段的顺序?

编辑:我想继续在模板中循环。在管理员和任何模板中获得正确的顺序也是很好的。模板更重要。

2 个答案:

答案 0 :(得分:1)

我可能会利用继承并执行类似的操作:

class ServerForm(ModelForm):

  def __init__(self, *args, **kwargs):
    super(ServerForm, self).__init__(*args,**kwargs)
    self.fields['name'] = forms.CharField(max_length=255, required=True)

    class Meta:
      model = Server
      exclude = ["user","name"]


class ServerUpdateForm(ServerForm):
  delete = forms.BooleanField(required=False)

  def __init__(self, *args, **kwargs):
    super(ServerForm, self).__init__(*args,**kwargs)

  class Meta:
    model = Server
    exclude = ["user","name"]

答案 1 :(得分:0)

老问题,但我通过jQuery很容易做到这一点。它比弄乱Meta或为每个表单输入字段(特别是那些不能很好地继承的字段)要快得多。我在管理页面中使用它:

$("selector_for_field").insertBefore($(".form-row:first"));

根据表单布局的需要调整选择器。