如何根据用户输入动态更改 django 中的表单(提交前)
Posted
技术标签:
【中文标题】如何根据用户输入动态更改 django 中的表单(提交前)【英文标题】:How to dynamically change a form in django based on user input (before submission) 【发布时间】:2020-12-05 18:36:13 【问题描述】:我正在做一个网页,其中包含一个必须根据之前的用户输入(在提交之前)动态更改的表单。例如,如果名称以字符串S.L
结尾,则需要自动跨越其余字段以引入公司数据,否则必须使用默认值或任何值提交表单。
表单继承自模型,所有内容都呈现为酥脆的表单。
在 views.py 我有:
@login_required
def form_home(request):
if request.method == 'POST':
Inputs = InputsForm(request.POST)
if Inputs.is_valid():
inp = Inputs.save(commit=False)
inp.author = request.user
inp.email = request.user.email
data = 'email': request.user.email, **Inputs.cleaned_data
obtain_calculate_create_send(data)
inp.save()
messages.success(request, f'Your form is valid!')
return redirect('result/' + str(inp.pk) + '/')
else:
messages.warning(request, f'Please, check the inputs and enter valid ones')
content = 'Inputs': Inputs, 'title': 'valuations'
else:
Inputs = InputsForm(request.POST or None)
content = 'Inputs': Inputs, 'title': 'valuations'
return render(request, 'valuations/form_home.html', content)
在forms.py中:
class InputsForm(forms.ModelForm):
# Basic Info
country_choices = import_lists('Countries', equal=True)
years = import_lists('years')
name = forms.CharField(label='Company Name', initial='Example. S.L')
country = forms.TypedChoiceField(choices=country_choices, label='Country')
foundation_year = forms.TypedChoiceField(coerce=int, choices=years, label='Foundation year')
employees = forms.IntegerField(label='Number of employees')
industry = forms.TypedChoiceField(choices=industry_choices, label='Industry')
class Meta:
model = Inputs
exclude = ('author', 'email', 'date_inputs_created ')
在models.py中:
class Inputs(models.Model):
def __str__(self):
return f'self.author´s inputs for self.name created at self.date_inputs_created'
# Useful information for the data base
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_inputs_created = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=254, default='example@compani.com')
# Actual inputs
# Basic Info
# ---------
country_choices = import_lists('Countries', equal=True)
industry_choices = import_lists('Industry', equal=True)
name = models.CharField(max_length=100)
country = models.CharField(max_length=30, choices=country_choices, default='Germany')
foundation_year = models.PositiveSmallIntegerField(choices=years)
employees = models.PositiveIntegerField(default=20)
industry = models.CharField(max_length=50, choices=industry_choices)
在 HTML 中:
% block content %
<form method="post">
% csrf_token %
Inputs|crispy
<button type="submit" class="btn btn-primary">submit</button>
</form>
% endblock %
感谢任何帮助,提前致谢。
【问题讨论】:
【参考方案1】:为了让您了解如何改变它,我认为可以通过三种方式实现。
使用 Django Signals 运行预保存函数,检查名称是否包含“S.L”并相应地应用字段逻辑。
更改您的视图功能并在那里应用逻辑。
劫持您的模型保存方法并检查名称是否包含“S.L”并在那里应用逻辑。
我会选择选项 3,因为它更简单、更快。举个例子,在 Inputs 模型定义中添加以下代码
def save(self, *args, **kwargs):
name= self.name
if name.endswith("S.L"):
self.country = 'Company country'
self.foundation_year = 'Company year'
.... And so on ...........
super().save(*args, **kwargs)
上述代码的工作原理是,对于每个传入的数据,它都会检查名称是否以“S.L”结尾并更改逻辑。
您可以更改视图逻辑并应用此条件,但如果您不想更改当前视图定义,也可以这样做。
如果你想尝试选项 2,那么,试试这个
if request.method == 'POST':
Inputs = InputsForm(request.POST)
if Inputs.is_valid():
inp = Inputs.save(commit=False)
inp.author = request.user
inp.email = request.user.email
# CODE -----------------------
name = inp.name
if name.endswith("S.L"):
inp.country = 'Company country'
inp.foundation_year = 'Company year'
.... And so on ...........
#CODE ! ----------------------
data = 'email': request.user.email, **Inputs.cleaned_data
obtain_calculate_create_send(data)
inp.save()
messages.success(request, f'Your form is valid!')
return redirect('result/' + str(inp.pk) + '/')
else:
messages.warning(request, f'Please, check the inputs and enter valid ones')
content = 'Inputs': Inputs, 'title': 'valuations'
else:
Inputs = InputsForm(request.POST or None)
content = 'Inputs': Inputs, 'title': 'valuations'
return render(request, 'valuations/form_home.html', content)
【讨论】:
嗨,问题是,如果它提交的表单,这将起作用,但我需要的是显示给用户的字段会根据输入动态变化,而无需提交该输入。例如,您填写一个字段,然后出现新字段而不提交,然后您提交所有已填写的字段,其余字段显示为空值或默认值。以上是关于如何根据用户输入动态更改 django 中的表单(提交前)的主要内容,如果未能解决你的问题,请参考以下文章