每个外键的formset和输入文本

时间:2014-07-07 10:44:32

标签: django input initialization foreign-keys formset

在我的django formset中,我正在尝试使用foreign key代替input来显示select字段:

class MinAttend(models.Model):
    act = models.ForeignKey(Act)
    country = models.ForeignKey(Country)
    verbatim = models.ForeignKey(Verbatim)
    def __unicode__(self):
        return u"%s" % self.verbatim

class MinAttendForm(forms.ModelForm):
    country=forms.ModelChoiceField(queryset=Country.objects.all(), empty_label="Select a country")
    status=forms.ModelChoiceField(queryset=Status.objects.values_list('status', flat = True).distinct(), empty_label="Select a status")
    verbatim=forms.CharField(max_length=300)

    class Meta:
        model=MinAttend
        #fields used for the validation and order
        fields = ('country', 'status', 'verbatim')

对于逐字字段,我确实有一个输入框而不是选择,但是当我想要更新一个formset时,我有一个verbatim id而不是相应的文本:

enter image description here

以下是我初始化表单的方法:

class MinAttendUpdate(UpdateView):
    object=None
    model = MinAttend
    form_class=MinAttendForm
    nb_extra_forms=3

    def post(self, request, *args, **kwargs):
        attendances=MinAttend.objects.filter(...)
        #set the number of forms to the number of ministers + 3 extra form to fill if needed
        MinAttendFormSet = modelformset_factory(self.model, form=self.form_class, extra=len(attendances), max_num=len(attendances)+self.nb_extra_forms, can_delete=True)
        formset=MinAttendFormSet(queryset=attendances)

我尝试了两件事:

而不是最后一行,我有以下代码:

initials=[]
#display text of verbatim instead of id
for index in range(len(attendances)):
    initials.append({"verbatim": attendances[index].verbatim.verbatim})
print "initials", initials
formset=MinAttendFormSet(queryset=attendances, initial=initials)

我已覆盖表单的init方法:

#~ #verbatim text instead of id for the verbatim field
def __init__(self, *args, **kwargs):
    super(MinAttendForm, self).__init__(*args, **kwargs)
    instance = kwargs.get("instance", None)
    if instance!=None:
        print "instance", instance.verbatim.verbatim
        self.fields["verbatim"].initial = instance.verbatim.verbatim

这些方法都不起作用,我仍然得到数字而不是文字!令人好奇的是,我确实看到了逐字字段的文本,但仅针对三种额外的形式。正常?

编辑 - 来自Bernd Jerzyna的评论

以我的形式

from django.forms.models import BaseModelFormSet

class MinAttendFormSet(BaseModelFormSet):
    def __init__(self, *args, **kwargs):
        super(MinAttendFormSet, self).__init__(*args, **kwargs)
        for form in self.forms:
            #skip extra forms
            if not form.empty_permitted:
                form.fields['verbatim'].initial= form.instance.verbatim
                print "verbatim MinAttendFormSet", form.instance.verbatim

在我的视图

from forms import MinAttendForm, MinAttendFormSet
my_formset = modelformset_factory(self.model, form=self.form_class, formset=MinAttendFormSet)
formset = my_formset(request.POST, queryset=attendances)

当我打印每个逐字的文本时,我看到显示正确的文字。但是,我仍然以网页的形式看到数字(主键ID);(。

出了什么问题?

2 个答案:

答案 0 :(得分:0)

我认为这样的事情应该有效:

实施formset的 init 方法,如

def __init__(self, *args, **kwargs):
...
super(MinAttendFormSet, self).__init__(*args, **kwargs)

for form in self.forms:
     form.fields['verbatim'].initial= form.instance.verbatim

这也需要你的Verbatim模型有类似的东西:

def __unicode__(self):
    return u'%s' % (self.name)

答案 1 :(得分:0)

这是我对它的理解......

作为选择小部件,逐字显示__unicode__个结果,但“幕后”值为PK / verbatim-id, HTML {{1标签有一个值和'标签'。当您将其更改为文本输入窗口小部件时,它期望您输入PK,因此您可以看到这些数字。

对于解决方案,我不确定。您可以编写一些代码来接受逐字文本,而不是pk / verbatim-id。但问题是,如果文本没有写入,django将找不到匹配项。此外,如果多于1个逐字文本具有相同的文本,则django将不知道使用哪个文本(除非您在模型字段上为文本设置了unique=true)。您也可以将逐字文本设置为PK。

也许使用类似Django-Select2的内容会为您提供所需的用户界面?