user3184033
user3184033

Reputation: 37

Django ModelForm with foreign key

I'm trying to create a ModelForm that updates a table with foreign keys. What I have seems to work, but I was hoping someone could tell me if there's a better way to do this or if there's a problem with the way I'm doing it below.

Is it correct to use the queryset on the Author and Genres table? It feels like I should be using a queryset on the Book model, and relate the foreign key to those tables.

models.py:

class Author(models.Model):
    name = models.CharField(max_length=200)
    
class Genre(models.Model):
    name = models.CharField(max_length=200)
    
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author')
    genre = models.ForeignKey('Genre')

forms.py:

class BookForm(ModelForm):
    title = forms.CharField(max_length=200)
    author = forms.ModelChoiceField(queryset=Author.objects.all())
    genre = forms.ModelChoiceField(queryset=Genre.objects.all())

    class Meta:
        model = Book
        fields = ['title', 'author', 'genre']

views.py:

def add_book(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return HttpResponseRedirect('/add/')
    else:
        form = BookForm()

Upvotes: 1

Views: 5572

Answers (2)

Alvaro
Alvaro

Reputation: 12037

The only thing that's wrong with this code is you are overriding the default behaviour of your model form. Change it to look like:

class BookForm(ModelForm):

    class Meta:
        model = Book
        fields = ['title', 'author', 'genre']

And let django handle with the definition of those. if you need to add labels or widgets, you can define them in the Meta class:

class BookForm(ModelForm):

     class Meta:
         model = Book
         fields = ['title', 'author', 'genre']
         labels = {'title': 'Book title', }

For example.

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 600026

I'm not really sure what you're asking here, or why you would want a queryset on Book.

You haven't actually changed any of the defaults on any of the fields, so there is no need to redefine them: your form could be simply

class BookForm(ModelForm):
    class Meta:
        model = Book

and it would work exactly the same.

Upvotes: 0

Related Questions