【问题标题】:form and ModelMultipleChoiceField with existing data具有现有数据的表单和 ModelMultipleChoiceField
【发布时间】:2017-10-09 18:39:50
【问题描述】:

This post 在这个问题上很有帮助。但是,我正在使用基于类的视图,并且想知道当查询集依赖于我正在使用的模型的实例时,如何完成将“选定”项添加到 ModelMultipleChoiceField 的任务。

型号:

class OfferGroup(models.Model):
    name = models.CharField(max_length=64, null=False)
    priority = models.IntegerField(null=False, unique=True)

    class Meta:
        verbose_name = _('OfferGroup')
        ordering = ['priority', ]


class ConditionalOffer(AbstractConditionalOffer):
    groups = models.ManyToManyField('auth.Group', verbose_name=_("User Groups"), blank=True)
    offer_group = models.ForeignKey(OfferGroup, related_name='offers', null=True)
    ...
    class Meta:
        ordering = ['priority', ]

AbstractConditionalOffer 提供字段“name”、“offer_type”、开始和结束日期时间以及其他模型的外键。

表格:

class OfferGroupForm(forms.ModelForm):
    offers = ModelMultipleChoiceField(queryset=ConditionalOffer.objects.all(),
        widget=forms.widgets.SelectMultiple(), required=False)

class Meta:
    model = OfferGroup
    fields = ('name', 'priority', 'offers')

这个表格不是我真正需要的,见下文

查看:

class OfferGroupUpdateView(UpdateView):
    model = OfferGroup
    template_name = 'dashboard/offers/offergroup_edit.html'
    form_class = OfferGroupForm
    success_url = reverse_lazy('dashboard:offergroup-list')

    def save_offers(self, offer_group, form):
        selected_offers = form.cleaned_data['selected']
        for offer in selected_offers:
            offer_group.offers.add(offer, bulk=False)
        other_offers = form.cleaned_data['not_selected']
        for offer in other_offers & offer_group.offers.all():
            offer_group.offers.remove(offer)
        form.save()
        return HttpResponseRedirect(reverse('dashboard:offergroup-list'))

    def form_valid(self, form):
        offer_group = form.save(commit=False)
        return self.save_offers(offer_group, form)

现在,这种方法的问题在于,提供给 OfferGroupForm 的查询集没有提供任何关于选择了哪些优惠以及哪些优惠不是我要编辑的 OfferGroup 实例的任何信息:

我需要的是类似的东西

og = OfferGroup.objects.get(pk=current offer_groups primary key)
selected = ConditionalOffers.objects.filter(offer_group=og)
other = ConditionalOffers.objects.exclude(offer_group=og)

这样在呈现视图时,带有当前报价组(正在编辑的报价组)的外键的报价显示为已选中

此外,有没有办法在基于类的视图中使用模型表单来做到这一点?

如果我提供的代码有点模糊,请原谅我——我试图展示最显着的 sn-ps。

提前谢谢你!

【问题讨论】:

  • 为了简化:如何创建一个 MultiSelect 小部件,其中的项目根据它们是否被表单模型对象的外键引用而选择。我可以将所有 ConditionalOffers 添加到 MultiSelect,如何将其中一些设置为选中?

标签: django forms django-forms django-views


【解决方案1】:

解决方法是覆盖视图中的get_context_data方法:

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # get the current obj
    obj = context.get('offergroup')
    # use the current object to get related objects
    qs = ConditionalOffer.objects.filter(offer_group=obj)
    # add context variables that can be used in the template
    context['selected'] = qs.values_list('name', flat=True)
    context['offers'] = ConditionalOffer.objects.all().exclude(offer_group=obj)
    return context

【讨论】:

    猜你喜欢
    • 2011-07-19
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多