Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django form dropdown list of stored models

I am trying to create a form for a library where a user can perform 2 actions: add a new book or open the stored information of an existing one. Books have 2 fields (title and author). Every time a new book is created, it is stored at the database. Any previously created book is shown as an option at a dropdown list (only the name). I want that when a user selects an option from the dropdown list, the information of the selected book appears on screen.

I have been trying 2 different approaches, but none of them fulfills my requirements. On one hand, following this question django form dropdown list of numbers I am able to create a dropdown list, and get the selected value at views with some code like that:

class CronForm(forms.Form):
    days = forms.ChoiceField(choices=[(x, x) for x in range(1, 32)])

def manage_books(request):
    d = CronForm()
    if request.method == 'POST':
        day = request.POST.get('days')

But I want my options to be the previously stored books at the data base, and not pre-defined values.

An other approach I have tried is to do it from the html template. There I create the following form:

<form>
    {% for book in list %} 
        <option value="name">{{ book.name }}</option>
    {% endfor %}   
</form>

Where book is rendered at views from this:

l = Books.objects.all().order_by('name')

In this second case the information shown at the dropdown list is the one I want, but I don't know how to get the selected value and use it at views. Perhaps using a javascript function?

So my 2 requirements are: show the correct info at the list (the stored at the DB by the user) and be able to know which one has been selected.

like image 504
toni Avatar asked Apr 17 '13 08:04

toni


1 Answers

You should use ModelChoiceField.

class CronForm(forms.Form):
    days = forms.ModelChoiceField(queryset=Books.objects.all().order_by('name'))

Then your views, it should look something like this:

def show_book(request):
   form = CronForm()
   if request.method == "POST":
      form = CronForm(request.POST)
      if form.is_valid:
         #redirect to the url where you'll process the input
         return HttpResponseRedirect(...) # insert reverse or url
   errors = form.errors or None # form not submitted or it has errors
   return render(request, 'path/to/template.html',{
          'form': form,
          'errors': errors,
   })

To add a new book or edit one, you should use a ModelForm. Then in that view you'll check if it's a new form or not

book_form = BookForm() # This will create a new book

or

book = get_object_or_404(Book, pk=1)
book_form = BookForm(instance=book) # this will create a form with the data filled of book with id 1
like image 146
J. Ghyllebert Avatar answered Sep 24 '22 23:09

J. Ghyllebert