gccallie
gccallie

Reputation: 127

Django access foreignkey fields in a form

I'm working on a Virtual Library app (using Django v2.1, python v3.5) where anyone should be able to access the book catalog and request a loan by simply leaving some personal info like name, surname, email, etc.

These are some of the models in models.py:

class Profile(models.Model):
    name = models.CharField(max_length=50)
    # more fields like surname, email, phone...

class TrackBook(models.Model):
    # Somefields to keep track of date and status...
    borrower = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=True, blank=True)

class Book(TrackBook):
    #info about title, author, etc.

What I'm trying to do is to update a Book instance's borrower with a Profile instance that I created in the Form.

1)I've tried directly accessing borrower fields in a BookForm, but it didn't work.

# views.py
class BookRequestView(UpdateView):
    template_name = 'core/book_request.html'
    model = Book
    form_class = BookProfileForm

#forms.py
class BookProfileForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['borrower']

# book_request.html
<form class="" action="" method="post">
  {% csrf_token %}
  <div class="row">
    {{ form.borrower.name }}
    <! -- and all other fields -->
  </div>
    {% for field in form.hidden_fields %}
      {{ field }}
    {% endfor %}
  <button type="submit" class="btn btn-block btn-success btn-flat">Save</button>
 </form>

2) I've tried creating an inlineformset_factory() of Profile model but it doesn't work since what I want to achieve is create a profile form inside the book form, not viceversa. So the example here is not what I'm looking for.

Maybe I'm going out of my mind for a very simple thing, but I can't seem to find any compatible solution for this problem... Any help/suggestion is welcome. Thanks in advance.

Upvotes: 2

Views: 2724

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599490

You need a form based on Profile, not Book. Your view then needs to create the profile and then set the book's borrower to that.

class BookProfileForm(forms.ModelForm):
    book = forms.ModelChoiceField(queryset=Book.objects.all())
    class Meta:
        model = Profile
        fields = ['name', 'address',...]

class BookRequestView(CreateView):
    template_name = 'core/book_request.html'
    model = Book
    form_class = BookProfileForm

    def form_valid(self, form):
        borrower = form.save()
        book = Book.objects.get(self.kwargs['book_id'])  # or whatever is in your URL
        book.borrower = borrower
        book.save()
        return redirect(self.get_success_url())

Upvotes: 2

Related Questions