【问题标题】:Django: Different views for POST and GET - Form validation errorsDjango:POST 和 GET 的不同视图 - 表单验证错误
【发布时间】:2018-06-18 20:54:51
【问题描述】:

我有一个DemandDetailView(DetailView)BidCreationView(CreateView)

DemandDetailView 页面上,有一个表单(用于创建投标)将数据发布到BidCreationView

如果form 无效,我不知道该怎么办。我想用form errors 再次呈现DemandDetailView 并保留相应的URL。

class DemandDetailView(DetailView):
    model = Demand
    template_name = 'demands/detail.html'


    def dispatch(self, request, *args, **kwargs):
        self.bid_creation_form = BidCreationForm(request.POST or None, request.FILES or None,request=request)
        return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['bid_creation_form']=self.bid_creation_form
        return context

class BidCreationView(CreateView):
    http_method_names = ['post']
    model = Bid
    form_class = BidCreationForm

    def get_success_url(self):
        return reverse_lazy("demands:demands")

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update({'request': self.request})
        return kwargs

    def form_valid(self, form):
        form.instance.demand_id = self.kwargs.pop('demand_id')
        return super().form_valid(form)

你有什么想法吗?我唯一的想法是使用会话,这可能不是最好的方法。

【问题讨论】:

    标签: python django django-forms django-views django-urls


    【解决方案1】:

    您可以使用表单对象中的 is_valid() 方法。比如:

    class DemandDetailView(DetailView):
        model = Demand
        template_name = 'demands/detail.html'
    
    
    def dispatch(self, request, *args, **kwargs):
        form = BidCreationForm(request.POST or None, request.FILES or None,request=request)
        if form.is_valid():
             self.bid_creation_form = form
        return super().dispatch(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['bid_creation_form']=self.bid_creation_form
        return context
    

    选项#2(个人选择):

    forms.py

    from django import forms
    from .models import Bid
    
    class BidCreationForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
            super(BidCreationForm, self).__init__(*args, **kwargs)
            for field in self.fields.values():
                field.widget.attrs = {"class": "form-control"}
    
        class Meta:
            model = Bid
            fields = ('user', 'demands', 'amount', 'transaction')
    

    查看表单中的 Meta 类。它显式调用投标模型和字段属性是指来自模型实例的投标字段。现在您可以在任何视图中调用此表单,而无需调用另一个视图。如果你想在这个表单中添加逻辑,比如计算总金额或类似的东西,那么也应该在表单中进行。一次编写代码,不要重复自己。

    【讨论】:

    • 如果我想将数据发布到调用 DemadDetailView 的 url 但我想将带有表单数据的发布请求发送到 BidCreationView,这将起作用。
    • 我猜这里是因为我没有看到您的 Forms.py,但按照您的代码,BidCreationForm 函数是创建一个投标模型实例。这可以在您的 forms.py 中完成。基本上,您想要的是将您的表单扩展为 form.ModelForm 类,因此它会映射您的投标模型实例。这种类型的代码非常易于维护和扩展,因为您的表单已经从您的模型实例创建了投标实例。在这种情况下,您可以从任何视图调用该表单并创建您的投标实例,而无需显式调用视图docs.djangoproject.com/en/2.0/topics/forms/modelforms
    猜你喜欢
    • 2011-04-03
    • 2015-12-31
    • 2013-06-08
    • 2015-12-16
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多