【问题标题】:Django: Why my objects do not add database correctly?Django:为什么我的对象没有正确添加数据库?
【发布时间】:2021-11-11 17:10:29
【问题描述】:

我正在做一个简单的 Django 项目,可以说我只是一个初学者。我在models.py 中有 2 个classes

from django.db import models
from django.db.models.deletion import CASCADE

class Category(models.Model):
    category_name=models.CharField(max_length=225,null=True)
    def __str__(self):
        return f"ID: {self.category_name}"

class Book(models.Model):
    cover_img = models.URLField(max_length=200, null=True)
    author=models.CharField(max_length=128,null=True)
    summery=models.TextField(max_length=1000,null=True)
    category = models.ForeignKey(Category,related_name="book_categories",on_delete=CASCADE,null=True)

    def __str__(self):
        return f"{self.cover_img} ,{self.author},{self.summery}"

在我网站的首页(Menu.html),我使用jinja为每个类别创建一个按钮:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
        <title>Menu</title>
    </head>
    <body>
        {% for cat in categories %}
        <a type="button" class="btn btn-danger" href="{% url 'cat_detail' cat.id %}">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-book" viewBox="0 0 16 16">
                <path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811V2.828zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
            </svg>{{cat.category_name}}
        </a>
        {% endfor %}
    </body>
</html>

然后,如果用户单击其中一个按钮,他/她将被重定向到包含具有相同category 的所有书籍的页面。在我项目的第二部分,我想为我的Database 实现adding objectsmethod。 我的views.py

from django.shortcuts import redirect, render
from .models import *

# Create your views here.


def first_page(request):
    context = {"categories" : Category.objects.all}
    return render(request, 'Menu.html', context)

def category_detail(request, id):
    try:
        my_object_base_category = Book.objects.filter(category__id=id)
    except Book.DoesNotExist:
        my_object_base_category = None
    return render(request, "Book.html", {'key':my_object_base_category})


def add_a_new_book(request):
    context = {"categories" : Category.objects.all}
    if request.method == "POST":
        cover_img = request.POST.get('cover_img')
        author = request.POST.get('author')
        summery = request.POST.get('summery')
        category = request.POST.get('category__category_name')
        myobj = Book(cover_img = cover_img , author = author , summery = summery, category = category)

        myobj.save()
        return render(request, "Menu.html")
    elif request.method == "GET":
        # print("Get in Create")
        return render(request, 'AddBook.html',context)

这是我在AddBook.html中的form

<form action="{% url 'Blog:add_book' %}" method="POST">
    {% csrf_token %}
    <div class="form-row">
        <div class="form-group col-md-6">
            <label for="author">Author</label>
            <input type="text" class="form-control" id="author" placeholder="Author">
        </div>
        <div class="form-group col-md-6">
            <label for="cover_img">Cover Image Link</label>
            <input type="url" class="form-control" id="cover_img" placeholder="Cover Image Link">
        </div>
    </div>
    <div class="form-group">
        <label for="summery">Summary</label>
        <input type="text" class="form-control" id="summery" placeholder="Summary">
    </div>
    <div class="form-group col-md-4">
        <label for="category">Category</label>
        <select id="category" class="form-control">
            {% for i in categories %}
            <option value="{{ i.category_name }}">{{ i.category_name }}</option>
            {% endfor %}
        </select>
    </div>
    <br><br><br><br><br><br><br><br><br>
    <input type="submit" class="btn btn-primary" value="add">
</form>

但是我的代码有两个问题。第一个是在我添加一个新对象后,它会保存所有等于NULL 的值。第二个是点击add按钮后,并没有重定向到另一个页面。这是我的应用程序中的urls.py 文件:

from django.urls import path
from . import views

app_name = 'Blog'

urlpatterns = [
    path('Menu/', views.first_page, name='category_buttons'),
    path('<int:id>/', views.category_detail, name='cat_detail'),
    path('add', views.add_a_new_book, name='add_book')
]

我将非常感谢任何帮助或建议。谢谢。

【问题讨论】:

    标签: python html django


    【解决方案1】:

    您的 html 表单输入字段都需要具有 name 属性才能从 POST 请求中获取它们的值。如果表单中的输入没有name 属性,则它的值甚至根本不会在请求中传递。

    例如,您的作者输入字段应类似于:

    <input type="text" class="form-control" id="author" name="author" placeholder="Author">
    

    所有值都在数据库中存储为 Null 的原因是,当您尝试从视图中的请求中获取值时,请求找不到您要查找的键的值,所以它返回无。 例如,您在视图中的行

    author = request.POST.get('author')
    

    返回 None 是因为它找不到名为“author”的键,因为您在 html 中的输入均未命名为“author”。

    编辑回答您来自 cmets 的其他问题:

    这是假设您的类别名称都是唯一的。在您的表单中,您需要更改您的选择选项以获得名称。像这样的:

    <select id="category" class="form-control" name="category">
    

    在您的视图中,要获取您想要的类别对象,您应该执行以下操作:

    category = request.POST.get('category')
    category_object = Category.objects.get(category_name=category)
    

    然后在创建新书对象时将category_object 变量传递给它。

    myobj = Book(cover_img = cover_img , author = author , summery = summery, category = category_object)
    myobj.save()
    

    【讨论】:

    • 是的,现在它正确地将它添加到我的数据库中。但实际上,点击添加按钮后,它并没有转到Menu.html 。请大家多多帮助?,它也没有选择category,但我不知道为什么。
    • 一次一个问题。对于Menu.html 页面问题,您只是在保存对象后尝试重定向到该页面,还是尝试将相同的请求传递给该模板和/或该页面的视图?
    • 是的,我想在保存对象后重定向到该页面。我实际上没有明白这两种情况有什么区别。
    • 在您的 urls.py 文件中,您是否有用于呈现您的 Menu.html 页面的视图的路径?
    • 是的,我有。
    猜你喜欢
    • 2020-05-26
    • 2013-02-22
    • 1970-01-01
    • 2014-05-14
    • 2021-09-16
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多