在django中设置inlineformset需要 [英] Make inlineformset in django required

查看:188
本文介绍了在django中设置inlineformset需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚到django(到现在为止,我使用symfony PHP框架)。我的问题是这样的:
我有一个模型事件和模型日期。日期有一个外键到活动,所以一个事件可能(或应该)有一个或多个日期。



现在我想有一个表单来创建事件和此表单应包含一个子表单,用于添加一个相应的日期(如果事件有多个日期,则应该添加更多的日期)。



我使用内联表达式来实现日期子窗体,但是如果没有输入日期,则不会发生错误,并且事件在没有日期的情况下被保存。所有我想要的是使这个内联形式需要或说,必须有一个内联形式集(和只有)一个内联形式。



我发现这些问题,但没有一个答案帮助我:





任何提示给我?



编辑:我需要这个前端,而不是后端。第一个链接涵盖了管理员后端。



EDIT2:添加了一些源代码

MandatoryInlineFormSet.py:

  from django.forms.models import BaseInlineFormSet 
from django import forms

class MandatoryInlineFormSet BaseInlineFormSet):
def clean(self):
#获取实际有效数据的表单
count = 0
for self.forms中的表单:
try:
如果form.cleaned_data:
count + = 1
除了AttributeError:
#烦人的,如果子表单无效Django Explicit引发
#一个AttributeError为clean_data
pass
如果count< 1:
raise forms.ValidationError('您必须至少有一个订单')

event.py:

$ b

  from [...] 
def new(request):
DateFormset = inlineformset_factory(
事件,
日期,
can_delete = False,
extra = 1,
max_num = 1,
formset = MandatoryInlineFormSet,


如果request.POST:
form = EventForm(request.POST)
date_formset = DateFormset(request.POST)
如果form.is_valid():
event = form.save(commit = False)
date_formset = DateFormset(request.POST,instance = event)
如果date_formset.is_valid():
event.save()
date_formset.save()
return HttpResponseRedirect(reverse('frontpage'))
else:
form = EventForm()
date_formset = D ateFormset()
return render_to_response('event / new.html',{
'form':form,
'date_formset':date_formset,
},context_instance = RequestContext ))

event / new.html:

  [...] 
< form action ={%url new-event%}method =post>
{%csrf_token%}
{{form.as_p}}

{{date_formset.management_form}}
{date_formset.forms%}中的date_form%
{{date_form.as_p}}
{%endfor%}


< input type =submitvalue ={%trans创建事件% }/>
< / form>
[...]

最好的问候,
sewid

解决方案

我几乎意外绊倒了我自己。我有一个内联表格,它上面有一个模型框。那个modelchoice没有empty_label。所以在技术上并不完全是空白的。当其他字段被放在内联表单上时,它将显示验证错误(您可以轻松地在视图中测试,并且不保存主窗体,除非所有内联表单均有效)。



所以,看来你有两个选择:1)用无效文本填写日期表(即不是某个日期,帮助文本),当它留在那里并提交它无法验证,或2)将日期选择器重新设置为没有空白状态的下拉窗口小部件 - 从而强制用户选择某些东西(但您可能希望使用适当的JavaScript日期小部件,这将使多个下拉列表繁重。


I am new to django (until now, I used the symfony PHP Framework). My problem is this: I have a model Event and model Date. The Date has a foreign key to Event, so that an Event may (or should) have one or more Dates.

Now I want to have a form to create Events and this form should include a subform for adding one corresponding Date (more dates should be added later, if the Event has more than one date).

I used the inlineformset to realize the Date subform, but if no Date is being entered, no error occurs and the Event is being saved without a Date. All I want is to make this inlineformset required or to say, that there has to be at lease (and only) one inlineformset.

I found these questions, but none of the answers helped me:

Any hints for me?

EDIT: I need this for the frontend, not for the backend. The first link covers it for the admin backend.

EDIT2: Some sourcecode added

MandatoryInlineFormSet.py:

from django.forms.models import BaseInlineFormSet
from django import forms

class MandatoryInlineFormSet(BaseInlineFormSet):
    def clean(self):
        # get forms that actually have valid data
        count = 0
        for form in self.forms:
            try:
                if form.cleaned_data:
                    count += 1
            except AttributeError:
                # annoyingly, if a subform is invalid Django explicity raises
                # an AttributeError for cleaned_data
                pass
        if count < 1:
            raise forms.ValidationError('You must have at least one order')

event.py:

from [...]
def new(request):
    DateFormset = inlineformset_factory(
            Event,
            Date,
            can_delete=False,
            extra=1,
            max_num=1,
            formset=MandatoryInlineFormSet,
            )

    if request.POST:
        form = EventForm(request.POST)
        date_formset = DateFormset(request.POST)
        if form.is_valid():
            event = form.save(commit=False)
            date_formset = DateFormset(request.POST, instance=event)
            if date_formset.is_valid():
                event.save()
                date_formset.save()
                return HttpResponseRedirect(reverse('frontpage'))
    else:
        form = EventForm()
        date_formset = DateFormset()
    return render_to_response('event/new.html', {
        'form': form,
        'date_formset': date_formset,
        }, context_instance=RequestContext(request))

event/new.html:

[...]
<form action="{% url new-event %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}

    {{ date_formset.management_form }}
    {% for date_form in date_formset.forms %}
        {{ date_form.as_p }}
    {% endfor %}


    <input type="submit" value="{% trans "Create event" %}"/>
</form>
[...]

Best regards, sewid

解决方案

I've tripped over this myself almost by accident. I had an inline formset which had a modelchoicefield on it. That modelchoice had no empty_label. So it technically wasn't entirely blank. When other fields were left out on the inline form it would show validation errors (you can easily test for this in the view and not save the main form unless all the inline forms are valid).

So, it seems you are left with two options: 1) populate the date form with invalid text (i.e. not a date, "helper" text of some kind) that when left in there and submitted it fails to validate, or 2) rework your date selector to dropdown widgets that have no blank state - thus forcing the user to pick something (but you might prefer a proper javascript date widget, which would make multiple dropdowns onerous.

这篇关于在django中设置inlineformset需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆