【问题标题】:formset and input text for each foreign key每个外键的表单集和输入文本
【发布时间】:2014-08-27 19:51:03
【问题描述】:

在我的django formset 中,我试图用input 而不是select 显示foreign key 字段:

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')

对于逐字字段,我确实有一个输入框而不是一个选择,但是当我想更新一个表单集时,我有逐字 ID 而不是其相应的文本:

这是我初始化表单的方式:

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);(。

怎么了?

【问题讨论】:

    标签: django input initialization foreign-keys formset


    【解决方案1】:

    我认为这样的事情应该可行:

    实现表单集的 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)
    

    【讨论】:

    • 我不认为它可以工作,因为 init 方法是在我的表单 (class MinAttendForm(forms.ModelForm):) 中声明的,这意味着它一次只能看到一个表单。当我使用你的代码时,我收到错误:'MinAttendForm' object has no attribute 'forms'。接下来我该怎么办?
    • 是的,没错。这就是为什么我建议在表单集中实现它... :)
    • 我已根据您的上一条评论更新了我的第一篇文章。它仍然不起作用:(。
    【解决方案2】:

    这是我的理解……

    作为一个选择小部件,逐字显示与__unicode__ 结果,但“幕后”的值是PK/verbatim-id,ie HTML <option> 标签具有一个值和“标签”。当您将其更改为文本输入小部件时,它希望您输入 PK,因此您会看到数字。

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

    也许使用 Django-Select2 之类的东西会给你想要的 UI?

    【讨论】:

    • 如何实施您的解决方案?我的问题不是将逐字写入输入框,而是逐字显示。
    猜你喜欢
    • 2018-10-16
    • 2017-12-16
    • 2017-06-19
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多