django admin inline 用的同一个,其中一个是空,无法保存

django admin inline 用的同一个,其中一个是空,无法保存

django admin inline 用的同一个,其中一个是空,无法保存

在Django中,Admin是一个强大的工具,可以让开发者轻松管理数据库中的数据。其中的Inline功能可以让我们在一个页面上同时编辑多个相关联的模型。但有时候,在使用Inline的过程中会遇到一个问题:使用同一个Inline对象,但其中一个为空,导致无法保存数据。本文将详细介绍这个问题的原因和解决方法。

问题描述

假设有如下两个模型,一个是Parent,一个是Child,它们之间是一对多的关系。

from django.db import models

class Parent(models.Model):
    name = models.CharField(max_length=100)

class Child(models.Model):
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)

接下来,我们在Admin中定义Inline,让Child模型能够在Parent的编辑页面中进行编辑。

from django.contrib import admin
from .models import Parent, Child

class ChildInline(admin.TabularInline):
    model = Child

@admin.register(Parent)
class ParentAdmin(admin.ModelAdmin):
    inlines = [ChildInline]

在这种情况下,如果我们在Parent的编辑页面中同时添加了两个Child对象,但只填写了一个Child对象的信息,另一个Child对象为空,当我们尝试保存数据时,会发现无法成功保存,页面会提示“Please correct the errors below”。

问题原因

发生这种情况的原因是Django在处理Inline数据保存时,会检查每个Inline对象是否为空。如果其中一个Inline对象为空,那么Django会默认认为这是一个错误,因为在数据库中外键字段不能为空。

解决方法

为了解决这个问题,我们可以通过重载Inline的clean方法来处理。我们可以在ChildInline中添加一个clean方法,手动检查每个Inline对象是否为空,并将空的对象从数据中删除。

from django.contrib import admin
from .models import Parent, Child

class ChildInline(admin.TabularInline):
    model = Child

    def clean(self):
        super(ChildInline, self).clean()
        for form in self.forms:
            if form.cleaned_data.get('id') and not form.cleaned_data.get('name'):
                form.cleaned_data = {}
                form.cleaned_data[self._pk_key] = None

在上面的代码中,我们重载了clean方法,遍历每一个Inline对象的表单,如果发现其中的某个对象为空(没有填写name字段),则将该对象从数据中删除。

经过上述处理后,我们再次尝试在Parent的编辑页面上添加两个Child对象,但只填写一个Child对象的信息,另一个对象留空。此时保存数据就不会再出现错误了。这样就解决了使用同一个Inline对象时,其中一个为空导致无法保存数据的问题。

总结一下,通过重载Inline的clean方法,手动处理空对象可以解决这个问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程