Форма для отношения ManyToMany на странице сведений

У меня есть следующие (упрощенные) модели:

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

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

Я хочу отобразить страницу сведений о лоте, на которой указана вся информация о лоте, включая идеи, связанные с этим лотом. Это просто сделать.

Однако, кроме того, я хочу, чтобы пользователь мог добавить новую идею для этого лота с этой страницы. После отправки пользователь должен вернуться на страницу сведений о лоте со своей новой идеей, которая теперь является частью списка.

Я пробовал встроенные наборы форм для новой идеи, но это отображается только как раскрывающийся список существующих идей и не позволяет создать новую идею. Кроме того, это кажется излишним, поскольку мне нужно, чтобы пользователь мог добавить новую идею, а не редактировать/удалять уже отправленные идеи. И мне также не нужно, чтобы они могли редактировать другую информацию о лоте, только добавить связанную идею.

Я знаю, что, вероятно, есть простой способ добиться этого, но в данный момент я немного застрял.

Любая помощь будет оценена по достоинству.

Спасибо!

РЕДАКТИРОВАТЬ: я не имею в виду администратора Django. Это для пользовательских форм.


person Douglas Meehan    schedule 31.08.2013    source источник
comment
Я думаю, что, возможно, нашел ответ на свой вопрос здесь: docs.djangoproject.com/en/1.5/topics/class-based-views/mixins/. Я проверю это и посмотрю, работает ли это так, как нужно   -  person Douglas Meehan    schedule 01.09.2013


Ответы (2)


Рядом с вашим внешним ключом / полями M2M должна быть активная зеленая отметка +. Это позволит вам создать новый Idea, а затем вернуться к вашему экземпляру Lot.

Вот пример (с использованием filter_horizontal вместо ManyToManyField):

введите здесь описание изображения

person Kevin Christopher Henry    schedule 31.08.2013
comment
Спасибо за ответ. Но я не про админа. Я также не хочу переходить на другую страницу, чтобы добавить новую идею. Мне нужно, чтобы это произошло на той же странице. - person Douglas Meehan; 01.09.2013
comment
@ Дуглас: понятно. Я думаю, что администратор по умолчанию открывает новое окно/вкладку для нового элемента, а затем автоматически заполняет им исходную форму при сохранении. Если этого достаточно, вы можете просто посмотреть, что делает администратор, и скопировать это. В любом случае, я не думаю, что есть простое решение, если вы не можете найти приложение, которое предлагает эту функциональность в формах моделей. - person Kevin Christopher Henry; 01.09.2013
comment
@Douglas: вот вопрос, связанный с , хотя, к сожалению, он не нет полезного ответа. - person Kevin Christopher Henry; 01.09.2013

Вот решение, которое я нашел для работы: (ссылка: 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)
person Douglas Meehan    schedule 02.09.2013