繁体   English   中英

如何根据用户输入动态更改 django 中的表单(提交前)

[英]How to dynamically change a form in django based on user input (before submission)

我正在做一个 web 页面,其中包含一个必须根据以前的用户输入(在提交之前)动态更改的表单。 例如,如果名称以字符串SL结尾,则需要自动跨越字段的 rest 以引入公司数据,否则必须使用默认值或任何值提交表单。

该表单继承自 model 并且所有内容都呈现为一个松脆的表单。

在 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 信号运行预保存 function 以检查名称是否包含“SL”并相应地应用字段逻辑。

  2. 更改您的视图 function 并在那里应用逻辑。

  3. 劫持您的 Model 保存方法并检查名称是否包含“SL”并在那里应用逻辑。

我将 go 与选项 3,因为它更简单,更快。 举个例子,在Inputs model 定义中添加以下代码

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)

上述代码的工作原理是,对于每个传入的数据,它检查名称是否以“SL”结尾并更改逻辑。

您可以更改视图逻辑并应用此条件,但如果您不想更改当前视图定义,则可以这样做。

如果你想尝试选项 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM