Question

I have the following (simplified) models:

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

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

I want to display a Lot detail page that lists all the info about the lot, including ideas associated with that lot. This is simple to do.

However, in addition, I want the user to be able to add a new idea for that lot from this page. Upon submission, the user should return to the Lot detail page with their new idea now part of the list.

I've tried inline formsets for the new idea, but that only shows up as a drop down of existing ideas, it does not allow for a new idea to be created. Plus, it seems overkill as I only need the user to be able to add a new idea, not edit/remove ideas already submitted. And I also don't need them to be able to edit the other lot information, only add a related idea.

I know there is probably a simple way to achieve this, but I'm a bit stuck at the moment.

Any help would be appreciated.

Thanks!

EDIT: I'm not referring to the Django admin. This is for user facing forms.

Was it helpful?

Solution 2

Here's a solution I found to work: (ref: 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)

OTHER TIPS

There should be a clickable green + mark next to your foreign key / M2M fields. That will allow you to create a new Idea and then return to your Lot instance.

Here's an example (using filter_horizontal for the ManyToManyField):

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top