如何为使用Django CreateView创建的表单添加自定义样式

3

我对Django非常陌生。在跟随一些教程后,我已经成功使用Python通用视图(CreateView)创建了一个表单。

我有一个“问题”模型。

class Question(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField(max_length=2000)
    category = models.CharField(max_length=50)
    votes = models.IntegerField(default=0)
    asked_date = models.DateTimeField(default=datetime.now)

使用这个模型,我创建了一个视图类

class QuestionCreate(CreateView):
    model = Question
    fields = ['title', 'body', 'category']

这确实生成了一个漂亮的HTML表单。但是我如何为每个字段传递CSS属性呢?
5个回答

13
你可以为问题编写一个模型表单,并将其传递给创建视图。
class QuestionForm(forms.ModelForm):

    class Meta:
        model = Question
        fields = ('myfield1', 'myfield2) 
        widgets = {
        'myfield1': forms.TextInput(attrs={'class': 'myfieldclass'}),
        }

或者你可以重写init方法来为每个字段指定特定的类。
def __init__(self, *args, **kwargs):
    super(QuestionForm, self).__init__(*args, **kwargs)
    self.fields['myfield1'].widget.attrs.update({'class' : 'myfieldclass'})

然后,将其传递给CreateViewform_class属性,
class QuestionCreate(CreateView):
    model = Question
    form_class = QuestionForm

7

在基于Bootstrap框架的Django应用程序中,我遇到了类似的问题。我的第一次尝试:

# views.py
from django.views.generic.edit import UpdateView
from . import models

class ModuleUpdateView(UpdateView):
    model = models.Module
    fields = ['name', 'description', 'status']

看上去如下:

第一次尝试

确实不太好看!第二次尝试意味着为我的视图定义一个自定义ModelForm并在其中应用所有自定义内容:

# forms.py
from .models import Module

class ModuleForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ModuleForm, self).__init__(*args, **kwargs)
        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'form-control'

    class Meta:
        model = Module
        fields = ['name', 'description', 'status']

请注意__init__中的for循环,它将form-control CSS类添加到所有可见表单字段。 form-control 的 CSS 样式由 Bootstrap 提供,因此我甚至不需要修改我的样式表。
一旦我有了自定义的ModelForm,我可以按如下方式重写我的 View 类:
# views.py
from django.views.generic.edit import UpdateView
from . import forms, models

class ModuleUpdateView(UpdateView):
    model = models.Module
    form_class = forms.ModuleForm

你可以在下面看到结果。

第二次尝试

好多了!

希望这有所帮助,如果有问题,请随时评论。


4
class FooForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(FooForm, self).__init__(*args, **kwargs)
        self.fields['field1'].widget.attrs = { 'class': 'fooclass' }

    class Meta:
        model = FooModel
        fields = ['field1', 'field2']

您不能直接向CreateView添加css,您需要创建一个ModelForm并在创建视图中使用form_class = FooForm。在这个ModelForm中,您可以为字段使用特定的类,并根据需要使用css对其进行样式设置。


真是很不方便啊..人们会觉得在伴随着CreateView的HTML表单中有一种简单的方法来进行样式设置,但是调试表单对象时发现有包含空列表的CSS和JS列表的媒体字段,也许有一种方法可以添加一些样式。 - Vitaliy Terziev

1

最好的方法是重写get_form函数。

class QuestionCreate(CreateView):
    model = Question
    fields = ['title', 'body', 'category', 'MyField']

    def get_form(self, form_class=None):
        form = super(QuestionCreate, self).get_form(form_class)
        form['MyField'].field.widget.attrs.update({'class' : 'MyClass'})
        return form

或者,如果您想将属性添加到所有字段中,可以使用以下 for 循环:

class QuestionCreate(CreateView):
    model = Question
    fields = ['title', 'body', 'category', 'MyField']

    def get_form(self, form_class=None):
        form = super(OPCCreateView, self).get_form(form_class)
        for visible in form.visible_fields():
            visible.field.widget.attrs.update({'class' : 'MyClass'})
        return form

0
如果我们想要一些引导式样的渲染表单,我们可以使用django-crispy-forms:
pip install django-crispy-forms

接着将'crispy-forms'添加到已安装的应用程序中。
在表单模板页面中加载crispy_form_tags,并使用{{form|crispy}}代替{{form}}。

Crispy的文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接