1

我有这个模型:

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 以来,这不再起作用。

然后我在这里阅读: 如何在 Django ModelForm 中订购字段?

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

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

编辑:我很想继续在模板中循环。此外,在管理员以及任何模板中都有正确的顺序会很好。不过模板更重要。

4

2 回答 2

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"]
于 2014-10-01T14:28:19.627 回答
0

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

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

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

于 2018-03-08T15:27:05.007 回答