vmassuchetto
vmassuchetto

Reputation: 1569

Django embedded ManyToMany form

I need a special section into a form that I can't imagine how to do it by now. I'll try to make myself clear.

Suppose that I got a model like "Sale". That's naturally a set of products being sold. I don't want to select the products like on ManyToMany, I just want to have two CharFields like "Name" and "Price", and an "Add" button just besides. When I fill these fields and press "Add", there will be an ajax action that put a row into a box just below them. Same thing if I want to remove one of the rows by clicking in the "Remove" button in this row.

That's basically a ManyToMany field in such a way that I can insert them "on-the-fly".

I'm completely open to other solutions as well. Thanks.

Upvotes: 2

Views: 936

Answers (1)

Skylar Saveland
Skylar Saveland

Reputation: 11464

If it suits you, the whole thing could be most easily done with javascript. Create handlers for create/edit/delete. Create renders a blank form for a GET and validates/saves for a POST, adding the new item to the Sale it should belong to. Edit/Delete should follow fairly obviously.

I would probably just make the handlers render html partials, using javascript to pull the html into the dom for GET and alter the data with POSTs to the server.

Assuming the models,

class Sale(models.Model):
  items = models.ManyToMany('Item', related_name='sales')
  # ...

class Item(models.Model):
  # ...

Then we could create some handlers like this:

def create_item(request, saleID=""):
  sale = get_object_or_404(Sale, <ID>=saleID) # <- get the sale obj

  if request.method == 'POST':
    form = ItemForm(request.POST) # <- could take the sale here and do .add() in the save()
    if form.is_valid():
      i = form.save()
      sale.items.add(i) # <- or, add in the view here
      if request.is_ajax():
        return HttpResponse('ok')
      # redirect with messages or what have you if not ajax
  else:
    # make a blank form and whatnot
  # render the form

def edit_item(request, id|pk|slug=None):
  item = get_object_or_404(Item, slug=slug)
  if request.method == 'POST':
    # do the form is_valid, form save, return 'ok' if ajax, redirect if not ajax
  else:
    form = EditForm(instance=item)
  # render the form

def delete_item(request, id|pk|slug=None):
  if request.method == 'POST':
    # delete the item and redirect, or just return "ok" if is_ajax
  # render confirmation dialog

for the frontend code, I would use some combination of http://api.jquery.com/load/ http://api.jquery.com/jQuery.get/ and http://api.jquery.com/jQuery.post/ , etc but any javascript framework will do.

Upvotes: 1

Related Questions