How can I autofill a field in my django form in class based view?
I create an opportunity for users to comment on the book. I have a list of books, where all the books in the database are placed, and also a detail book for each book. I created a form for the possibility of commenting in detail book, where I pass various fields, but some I want to be autofilled not by the users themselves, such as the title of the book and the author. I managed to do it with the author, but the title of the book does not work. I would be grateful if you can help with this.
models.py
import uuid
from django.db import models
from django.db.models.enums import TextChoices
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
class Genre(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(
upload_to="photos", default=None, blank=True, null=True)
author = models.ForeignKey("Author", on_delete=models.SET_NULL, null=True)
summary = models.TextField()
isbn = models.CharField(max_length=10, unique=True, blank=True, null=True)
genre = models.ManyToManyField("Genre", related_name="book_genre")
publisher = models.ManyToManyField("Publisher")
languages = models.ManyToManyField("Language")
publication_date = models.DateTimeField(default=timezone.now)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("book_detail", kwargs={"pk": self.pk})
class Meta:
ordering = ["-created_date"]
constraints = [
models.UniqueConstraint(
fields=["title"], name="%(app_label)s_unique_booking"
)
]
class Publisher(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Language(models.Model):
class LanguageBook(models.TextChoices):
English = "Eng", _('English')
Spanish = "Es", _('Spanish')
Russian = "Rus", _('Russian')
German = "German", _('German')
Chinese = "Chinese", _('Chinese')
language_book = models.CharField(
max_length=10, choices=LanguageBook.choices, default=LanguageBook.English)
def __str__(self):
return self.language_book
# Author
class Author(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Meta:
ordering = ["first_name", "last_name"]
constraints = [
models.UniqueConstraint(
fields=["first_name", "last_name"], name="uniquename"
)
]
def get_absolute_url(self):
return reverse("author_detail", kwargs={"pk": self.pk})
def __str__(self):
"""String for representing the Model object."""
return f"{self.first_name} {self.last_name}"
class Review(models.Model):
book = models.ForeignKey(
Book, on_delete=models.CASCADE, related_name="reviews")
title = models.CharField(max_length=255)
body = models.TextField()
author = models.OneToOneField(User, on_delete=models.CASCADE)
created = models.DateTimeField(default=timezone.now)
def __str__(self):
"""String for representing the Model object."""
return self.body
forms.py
from django import forms
from .models import Author, Book, Review
class NewReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = ("title", "body")
views.py
from django.db.models import Q
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse_lazy
from django.urls import reverse
from django.views.generic.edit import FormMixin
from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
TemplateView, UpdateView)
from .filters import BookFilter
from .forms import AuthorForm, BookForm, NewReviewForm
from .models import Author, Book, Genre, Review
class BookDetailView(FormMixin, DetailView):
model = Book
template_name = "book-detail.html"
context_object_name = "book"
form_class = NewReviewForm
def get_success_url(self):
return reverse('book_detail', kwargs={'pk': self.object.id})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["author"] = Author.objects.all()
context['form'] = NewReviewForm(initial={'id': self.object})
return context
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.instance.author = self.request.user
form.save()
return super(BookDetailView, self).form_valid(form)
book-detail.html
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="row justify-content-md-center">
{% comment %} Image and update, delete {% endcomment %}
<div class="col-2 mt-5 ms-5 d-flex flex-column align-items-center">
{% if book.image %}
<img src="{{ book.image.url }}" alt="{{book.title}}" style="width:200px; height:200px">
{% else %}
<p>No Image</p>
{% endif %}
<a href="{% url 'book_update' book.id %}" class="d-flex align-items-center gap-1 mt-2"><svg
xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square"
viewBox="0 0 16 16">
<path
d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" />
<path fill-rule="evenodd"
d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z" />
</svg>Update information</a>
<a href="{% url 'book_delete' object.id %}"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
Delete Book</a>
</div>
{% comment %} End Image {% endcomment %}
{% comment %} Content {% endcomment %}
<div class="col-6 mt-5 ms-5">
<h1>{{book.title}}</h1>
<a href="{% url 'author_detail' book.author.id %}" class="color-primary">{{book.author}}</a>
{% comment %} start Google Translate {% endcomment %}
<div id="google_translate_element" class="text-end"></div>
{% comment %} End Google Translate {% endcomment %}
<p class="mt-5"><strong>Summary:</strong></p>
<p class="bold">{{book.summary}}</p>
<br>
<ul class="list-group mt-4">
<li class="list-group-item ">Book author: {{book.author}}</li>
<li class="list-group-item">Genre: {{ genre.book_genre.all }}</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
</ul>
<div>
{% comment %} Start review {% endcomment %}
<h1>Review</h1>
{% for review in book.reviews.all %}
<p>{{review.author}}</p>
<div class="notification">
<p>{{ review.created|date:"d-m-Y" }}</p>
</div>
<p>{{review.title}}</p>
<p>{{ review.body|linebreaks }}</p>
{% empty %}
<div class="notification">
No review yet ...
</div>
{% endfor %}
</div>
<div>
{% if request.user.is_authenticated %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Add comment">
</form>
{% else %}
<p>Please sign in to add review</p>
{% endif %}
</div>
{% comment %} End review {% endcomment %}
</div>
{% comment %} End comment {% endcomment %}
{% comment %} Loan {% endcomment %}
<div class="col-4 mt-5" style="width: 300px; height:100px">
<div class="card rounded-3 shadow-sm">
<div class="card-header py-3">
<h4 class="my-0 fw-normal tex-center">Loan</h4>
</div>
<div class="card-body">
<ul class="list-unstyled mt-3 mb-4">
<li>...</li>
</ul>
<button type="button" class="w-100 btn btn-lg btn-outline-primary">Take</button>
</div>
</div>
{% comment %} End Loan {% endcomment %}
</div>
</div>
{% endblock content %}