Django - 当用户提交表单时,会创建表,但表之间的连接不是

Posted

技术标签:

【中文标题】Django - 当用户提交表单时,会创建表,但表之间的连接不是【英文标题】:Django - when user submits a form, tables are created, but the connection between the tables is not 【发布时间】:2021-09-25 03:59:32 【问题描述】:

我正在做一个小项目,客户可以访问我的网站并注册与其姓名相关联的电话号码。这是一个连接方式注册(其中 number1 number2 是一个连接),因此每个会话只注册两个电话号码。查看特定电话号码时(例如,在管理员面板中),我想查看它所属的用户的 ID 以及它所属的连接的 ID。当我以相同的方式查看连接时,我想查看谁注册了该特定连接,以及在同一会话中注册的两个电话号码。

我的问题:所有外键给出“django.db.utils.IntegrityError: NOT NULL constraint failed”错误。我必须为要提交的客户数据的所有外键设置 null=True。 ManyToManyField 不会给出任何错误 - 但它不会像应有的那样将每个 Connection 限制为仅在会话中注册的两个电话号码。

因此,在添加数据时不会建立上述这种结构化连接。这就像每个电话号码和每个连接,每个用户都变成了自己的小岛,与其他桌子没有联系。当我点击管理面板中的“连接”时,已建立的每个连接都列在那里,但是当我选择它时,我看到 所有 曾经注册的电话号码。我选择的每一个连接都是一样的。当我选择一个电话号码时,没有任何东西可以将它连接到添加它的用户,或者它所属的“连接”。

我的 models.py 文件:

from django.db import models 

class Customer(models.Model):
    customer_name = models.CharField(max_length=100)
    customer_email = models.CharField(max_length=100)

class Phonenumber(models.Model):
    customer_number = models.CharField(max_length=100)
    belongs_to = models.ForeignKey(Customer, on_delete=DO_NOTHING)

class Connections(models.Model):
    registered_at = DateTimeField(auto_now=True)
    got_number_at = DateTimeField(default=None)  # this becomes the date the connection was made
    registered_by = models.ForeignKey(Customer, on_delete=DO_NOTHING)
    phonenumber_id = models.ManyToManyField(Phonenumber)

我的 phonebook_form.py 文件:

from django.forms import ModelForm
from django import forms
from .models import *

class CustomerForm(ModelForm):
    class Meta:
        model = Customer
        fields = ['name', 'email']

        widgets = 
            'name': TextInput(attrs='class':'form-control', 'id': 'cus_name')
            'email': TextInput(attrs='class':'form-control', 'id': 'cus_email')

class NumberForm(ModelForm):
    class Meta:
        model = Phonenumber
        fields = ['customer_number']

        widgets = 
            'customer_number': TextInput(attrs='class':'form-control', 'id': 'cus_number')

class ConnectionForm(ModelForm):
    class Meta:
        model = Connections
        fields = ['got_number_at']

        widgets = 
            'got_number_at': TextInput(attrs='class':'form-control', 'id': 'connection_date')

我的views.py 文件:

from django.shortcuts import render
from .phonebook_form import *

from1 = CustomerForm()
form2 = NumberForm()
form3 = ConnectionForm()

if request.method = "POST":
    form_customer = CustomerForm(request.POST)
    form_number = NumberForm(request.POST)
    form_connection = ConnectionForm(request.POST)
    if form_customer.is_valid():
        form_customer.save()
    if form_number.is_valid():
        form_number_save()
    if form_connection.is_valid():
        form_connection.save()

context = 'form1': form1,
           'form2': form2,
           'form3': form3
            

return render(request, 'phoneBook/phonebook.html') 

我还添加了数据库关系模式的图片:

我什至不知道从哪里开始解决这个问题。我已经看过很多 django 网站构建器教程并阅读了很多文章,并且所有这些似乎都以完全相同的方式进行,没有任何问题。我错过了什么? (虽然我已经使用python 2 年了,但我是 Django(1 周)和一般 Web 开发的完整初学者,所以修复越简单越好)

【问题讨论】:

好吧,你永远不会拯救PhoneNumber等客户。 我认为这是在views.py 中处理的,如果它有效的话在form_customer.save() 中处理? 它将检查电话 number 是否已连接(表单的字段),如果是,则在数据库中保存记录,但不会链接到碰巧保存在同一视图中的项目。 哦!这可以解释很多,是的。现在我只需要弄清楚如何做到这一点哈哈。关于我可以阅读/观看的主题,你碰巧有任何有用的资源吗? :) 【参考方案1】:

您的表单将检查电话号码是否正确(表单的字段),如果是,则在数据库中保存一条记录,但它不会链接到恰好保存在同一视图中的项目.并不是说您想以任何方式链接这些对象,或者可能有很多方法可以将其连接起来。因此,表单不会看起来是另一个表单构建的。程序员必须实现链接逻辑。

我们可以先检查所有的表单是否有效,然后用一个表单包裹的对象设置成另外一个表单包裹的对象,比如:

if form_customer.is_valid() and form_number.is_valid() and form_connection.is_valid():
    customer = form_customer.save()
    form_number.instance.belongs_to = customer
    phone_number = form_number_save()
    form_connection.instance.registered_by = customer
    connecion = form_connection.save()
    connection.phonenumber_id.add(phone_number)

注意:如果 POST 请求成功,您应该发送redirect [Django-doc] 实施Post/Redirect/Get pattern [wiki]。 这样可以避免在用户刷新时发出相同的 POST 请求 浏览器。

【讨论】:

以上是关于Django - 当用户提交表单时,会创建表,但表之间的连接不是的主要内容,如果未能解决你的问题,请参考以下文章

如果 django 表单提交失败,则运行 javascript

当表单出现错误时,带有 angular.js 表单提交的 Django 不起作用

提交表单html django

为啥我的表单创建一个新的模型对象而不是修改一个?

在我的 django 项目的 chrome 浏览器中按回“确认表单重新提交”

Cayenne - 搜索依赖组合