【问题标题】:Form for ManyToMany relationship on Detail page详细信息页面上的多对多关系表单
【发布时间】:2013-09-04 04:19:33
【问题描述】:

我有以下(简化的)模型:

class Idea(models.Model):
    tagline = models.TextField()

class Lot(models.Model):
    address = models.CharField()
    ...other fields...
    ideas = models.ManyToManyField(Idea)

我想显示一个批次详细信息页面,其中列出了有关该批次的所有信息,包括与该批次相关的想法。这很简单。

但是,此外,我希望用户能够从此页面为该批次添加新想法。提交后,用户应该返回到 Lot 详细信息页面,他们的新想法现在已成为列表的一部分。

我已经为新想法尝试了内联表单集,但这仅显示为现有想法的下拉列表,它不允许创建新想法。另外,这似乎有点矫枉过正,因为我只需要用户能够添加一个新想法,而不是编辑/删除已经提交的想法。而且我也不需要他们能够编辑其他地段信息,只需添加一个相关的想法。

我知道可能有一种简单的方法可以实现这一点,但我现在有点卡住了。

任何帮助将不胜感激。

谢谢!

编辑:我不是指 Django 管理员。这适用于面向用户的表单。

【问题讨论】:

标签: django forms manytomanyfield inline-formset detailview


【解决方案1】:

您的外键/M2M 字段旁边应该有一个可点击的绿色 + 标记。这将允许您创建一个新的 Idea,然后返回到您的 Lot 实例。

这是一个示例(使用filter_horizontal 表示ManyToManyField):

【讨论】:

  • 感谢您的回答。但我不是在谈论管理员。我也不想去另一个页面添加新想法。我需要让它发生在同一页面上。
  • @Douglas:我明白了。我认为默认的管理员行为是为新项目打开一个新窗口/选项卡,然后在保存时自动填充原始表单。如果这足够好,你可以看看管理员做了什么并复制它。无论哪种方式,我认为没有简单的解决方案,除非您可以找到在模型表单上提供此功能的应用程序。
  • @Douglas:这是related question,但不幸的是它没有有用的答案。
【解决方案2】:

这是我发现可行的解决方案:(参考:https://docs.djangoproject.com/en/1.5/topics/class-based-views/mixins/#using-formmixin-with-detailview

class LotDisplay(DetailView):
    model = Lot

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

class LotAddIdeaView(FormView, SingleObjectMixin):
    model=Lot
    form_class = IdeaForm
    template_name = 'lotxlot/lot_detail.html'

    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated():
            request.session['post'] = request.POST
            url = "%s?next=%s" % (reverse('account_login'), request.path)
            return HttpResponseRedirect(url)
        else:
            self.object = self.get_object()
            return super(LotAddIdeaView, self).post(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('lotxlot_lot_detail', kwargs={'pk': self.object.pk})

    def form_valid(self, form):
        """
         Auto-populate user
        and save form.
        """
        instance = form.save(commit=False)
        instance.user = self.request.user
        instance.save()
        instance.lots.add(self.object)
        instance.save()

        return HttpResponseRedirect(self.get_success_url())

class LotDetailView(View):
    def get(self, request, *args, **kwargs):
        view = LotDisplay.as_view()
        return view(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        view = LotAddIdeaView.as_view()
        return view(request, *args, **kwargs)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-26
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多