Как сослаться на столбец имени автора из таблицы Author в функции InsertBook?
(https://i.sstatic.net/EiBqboZP.png)
В браузере я пытаюсь добавить новую книгу в таблицу books, но постоянно получаю ошибку Value от django, где, например, я не могу присвоить "'Virginia Woolf'": "Book.author" должен быть экземпляром "Author". После того как я ввожу все поля для добавления новой книги, а затем нажимаю кнопку Insert в браузере, я получаю ошибку Value. Ниже приведена структура моей sql-таблицы, а также соответствующие скрипты python для справки:
--Create the books table
CREATE TABLE books (
book_id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author_id INTEGER REFERENCES authors(author_id),
genre VARCHAR(50),
price DECIMAL(10, 2),
publisher VARCHAR(100),
--Adding the column for the ISBN to populate the table with an extra instance
isbn VARCHAR(20)
);
--Create the videos table
CREATE TABLE videos (
video_id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
genre VARCHAR(50),
price DECIMAL(10, 2),
publisher VARCHAR(100),
release_date DATE
);
views.py:
urls.py:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),
path('author/',views.author,name="author"),
path('author/Insert/',views.Insertauthor,name="Insertauthor"),
path('author/Edit/<int:author_id>/',views.Editauthor,name="Editauthor"),
path('author/Update/<int:author_id>/',views.Updateauthor,name="Updateauthor"),
path('author/Delete/<int:author_id>/',views.Deleteauthor,name="Deleteauthor"),
path('book/',views.book,name="book"),
path('book/Insert/',views.Insertbook,name="Insertbook"),
path('book/Edit/<int:book_id>/',views.Editbook,name="Editbook"),
path('book/Update/<int:book_id>/',views.Updatebook,name="Updatebook"),
path('book/Delete/<int:book_id>/',views.Deletebook,name="Deletebook"),
]
models.py:
from django.db import models
class Author(models.Model):
author_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
birthdate = models.DateField(default='1900-01-01')
nationality = models.CharField(max_length=100, default="Unknown")
class Meta:
db_table = 'authors'
class Book(models.Model):
book_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
isbn = models.CharField(max_length=13, unique=True)
publisher = models.CharField(max_length=100)
genre = models.CharField(max_length=50, default="Unknown")
price = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
class Meta:
db_table = 'books'
admin.py:
from django.contrib import admin
from .models import Author, Book
# Register your models here.
admin.site.register(Author)
admin.site.register(Book)
Insert_book.html
<!DOCTYPE html>
<html>
<head>
<title>DjangoBookStore</title>
</head>
<body>
<center>
<h1>DjangoBookStore</h1>
<hr/>
<form method="POST">
{% csrf_token %}
<table border="1">
<tr>
<td>Book ID</td>
<td><input type="text" placeholder="Enter Book ID.." name="book_id"></td>
</tr>
<tr>
<td>Title</td>
<td><input type="text" placeholder="Enter Book Title.." name="title"></td>
</tr>
<tr>
<td>Author</td>
<td><input type="text" placeholder="Enter Author.." name="author"></td>
</tr>
<tr>
<td>ISBN</td>
<td><input type="text" placeholder="Enter ISBN.." name="isbn"></td>
</tr>
<tr>
<td>Publisher</td>
<td><input type="text" placeholder="Enter Publisher.." name="publisher"></td>
</tr>
<tr>
<td>Genre</td>
<td><input type="text" placeholder="Enter Genre.." name="genre"></td>
</tr>
<tr>
<td>Price</td>
<td><input type="text" placeholder="Enter Price.." name="price"></td>
</tr>
<tr>
<td><input type="submit" value="Insert"></td>
<td> {% if messages %}
{% for mess in messages %}
<b style="color: green;">{{mess}}</b>
{% endfor %}
{% endif %}
</td>
</tr>
</table>
<a href="{% url 'index' %}">Home Page</a>
</form>
</center>
</body>
</html>
book_list.html
<!DOCTYPE html>
<html>
<head>
<title>DjangoBookStore</title>
</head>
<body>
<center>
<h1>DjangoBookStore</h1>
<hr/>
<a href="{% url 'Insertbook' %}">Create New Book</a>
<table border = "1">
<tr>
<th>Book ID</th>
<th>Title</th>
<th>Author</th>
<th>ISBN</th>
<th>Publisher</th>
<th>Genre</th>
<th>Price</th>
</tr>
{% for book in books %}
<tr>
<td>{{book.book_id}}</td>
<td>{{book.title}}</td>
<td>{{book.author}}</td>
<td>{{book.isbn}}</td>
<td>{{book.publisher}}</td>
<td>{{book.genre}}</td>
<td>{{book.price}}</td>
<td><a href="Edit/{{book.book_id}}">Edit</a></td>
<td><a href="Delete/{{book.book_id}}" onclick="return confirmation('Are You Sure You Want To Delete The Record?')">Delete</a></td>
</tr>
{% endfor %}
</table>
</center>
</body>
</html>
Для решения проблемы я попробовал изменить ссылку в функции views.py Insertbook с saverecord.author=request.POST.get('author') на saverecord.author.name=request.POST.get('author'), которая выдает другую ошибку, что author не является столбцом в таблице books.
В ошибке указано, что вместо объекта Author в объекте books вы отправляете текст.
Проблема в этой строке
saverecord.author=request.POST.get('author')
Есть два способа исправить это.
Грязный способ, который будет работать с минимальными изменениями, но вам нужно ввести имя автора точно так же, как оно сохранено в DB. Просто измените строку № 59 следующим образом
saverecord.author=Author.objects.get(name=request.POST.get('author'))
Лучший подход, изменить автора с текстового поля на выпадающее, это обеспечит выбор только существующего автора. Для реализации этого подхода необходимо передать список авторов в html и отобразить его в виде выпадающего списка
.
Лучший способ использовать форму django ссылка