我已经在views.py文件中看到了一种执行我想要的方法的方法,但是由于我可能要在几个不同的地方使用该表单,并且因为我相信它更多地属于forms.py,所以我想知道是否以及如何在不修改视图的情况下用一个特定用户的数据库中已经存储的数据来预填充表单。看到我尝试过的东西会说明一切:
models.py:
class Customers(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='details')
city = models.CharField(max_length=50, blank=True, null=True)
dpt = models.IntegerField(blank=True, null=True)
adress = models.CharField(max_length=100, blank=True, null=True)
cplt_add = models.CharField(max_length=100, blank=True, null=True)
phone = models.CharField(max_length=14, blank=True, null=True)
forms.py:
class CustomerForm(ModelForm):
def __init__(self):
for field in self.fields:
user_infos = Customers.objects.get(pk=request.user.details.id)
initial_value = user_infos.field
field(initial=initial_value)
def clean_form(self):
...
class Meta:
model = Customers
fields = ['city', 'adress', 'dpt', 'cplt_add', 'phone']
widgets = {
'city': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Ville'}),
'dpt': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Département'}),
'adress': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Adresse'}),
'cplt_add': TextInput(attrs={
'class': 'form_input',
'placeholder': "Complément d'adresse"}),
'phone': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Téléphone'}),
}
不幸的是,这段代码返回了:
'CustomerForm'对象没有属性'fields'
关于如何通过良好实践方法做到这一点的任何建议?
答案 0 :(得分:2)
您以错误的级别解决了该问题:Django已经对此提供了支持,并且用__init__
自己编写它不是一个好主意(某些特定的除外)边缘和拐角案例)。
因此,您可以从__init__
中删除ModelForm
替代项:
# app/forms.py
class CustomerForm(ModelForm):
# remove the __init__ override
class Meta:
model = Customers
fields = ['city', 'adress', 'dpt', 'cplt_add', 'phone']
widgets = {
'city': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Ville'}),
'dpt': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Département'}),
'adress': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Adresse'}),
'cplt_add': TextInput(attrs={
'class': 'form_input',
'placeholder': "Complément d'adresse"}),
'phone': TextInput(attrs={
'class': 'form_input',
'placeholder': 'Téléphone'}),
}
在视图中(或您要构造表单的其他地方),我们可以通过构造函数的instance=
参数传递实例:
# app/views.py
def my_view(request):
customer=Customers.objects.get(pk=request.user.details.id)
my_form = CustomerForm(instance=customer)
# ...
# return HttpResponse object
然后Django将确保这些值以正确的形式填写(就像它是initial
值一样)。如果同时提供initial
值和instance
,则initial
的优先级如documentation on the ModelForm
中所述:
与常规表单一样,可以在实例化表单时通过指定
initial
参数来为表单指定初始数据。通过这种方式提供的初始值将覆盖表单字段中的初始值和附加的模型实例中的值。