Django-如何按名称验证数据

时间:2018-07-09 23:58:17

标签: python django django-forms

我有一个表单集,最近在其中一个字段中添加了带有jQuery的自动填充文本框。自动完成功能是一个文本框,可根据产品名称自动完成文本。由于它是一个文本字段,而不是以前的选择字段,因此我需要输入PK才能使表单真正正确地进行验证。我尝试添加一个自定义清理函数,该清理函数通过输入的名称查询数据库并输出正确的对象,但是django验证似乎甚至无法运行清理,并在甚至可以运行cleanign函数之前拒绝该表单。

请原谅这里似乎不太有意义的一些代码,我是新手。任何帮助将不胜感激!

如果有帮助,我在下面添加了我的代码。

views.py

def create_orderproduct_view(request, pk=None):
    order_number = get_object_or_404(Order, pk=pk)
    OrderProductFormSet = formset_factory(OrderProductForm)
    if request.method == 'POST':
        formset = OrderProductFormSet(request.POST)
        for x in formset:
            if x.is_valid() and 'Product_ID' in x.cleaned_data:
                x.save()
            else:
                return HttpResponseRedirect(reverse('orderproduct', kwargs={'pk':pk}))
    else:
        formset = OrderProductFormSet()
    return render(request, 'create_orderproduct.html', {'formset': formset})

forms.py

class OrderProductForm(ModelForm):
    class Meta:
        model = OrderProduct
        exclude = ('ID',)
        widgets = {
            'Product_ID' : AutoCompleteWidget()
        }
    def clean_Product_ID(self):
        Product_ID = self.cleaned_data['Product_ID']
        clean = Product.objects.get(Name__exact=Product_ID)
        return clean

widgets.py

#my custom widget
class AutoCompleteWidget(Widget):
    template_name = "widgets/auto_complete.html"

    def get_context(self, name, value, attrs=None):
        return {'widget' : {
            'name' : name,
            'value' : value,
        }}

    def render(self, name, value, attrs=None):
        context = self.get_context(name, value, attrs)
        template = loader.get_template(self.template_name).render(context)
        return mark_safe(template)

自动填充框

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
      $( function() {
        var availableTags = [
            'item 1',
            'item 2',
            'item 3',
            'item 4',
        ];
        $( ".my_class_name" ).autocomplete({
          source: availableTags
        });
      } );
  </script>

<input class='my_class_name' name="{{widget.name}}" id="{{widget.name}}" type='text'>

1 个答案:

答案 0 :(得分:0)

苦苦挣扎了几天之后,我设法找到了一个非常简单的解决方案,但我不确定该怎么错过。我接受了request.POST并使用正则表达式来过滤具有自动完成功能的字段。我对条目的名称进行了查询,并将其保存以保存pk而不是我的商品名称。这似乎是绕过Django验证的一种很好的方法,因为您正在更改要馈送到验证中的数据的结果。

下面为遇到此问题的其他人提供的代码: 免责声明:我不知道这是否是执行此操作的最佳方法,也无法保证它不会出错。使用风险自负。

views.py

def regex_query(request):
    pattern = re.compile(r'form.\d+.Product_ID')
    ## this is the name of my individual form
    post = request.POST.copy()
    for x in post:
        matcher = re.match(pattern, x)
        if matcher and post[x]:
            clean = Product.objects.get(Name__exact=post[x])
            post[x] = clean.pk

    return post 


def create_orderproduct_view(request, pk=None):
    OrderProductForm().fields['Room'].choices
    order_list = []
    order_number = get_object_or_404(Order, pk=pk)
    OrderProductFormSet = formset_factory(OrderProductForm)
    if request.method == 'POST':
        ## using regular expressions to identify the product, then query the result of the key to change the data
        request.POST = regex_query(request)
        ## saving over the request.POST
        formset = OrderProductFormSet(request.POST)
        for x in formset:
            if x.is_valid() and 'Product_ID' in x.cleaned_data:
                x.save()
... continues below ...