在调用保存方法前创建对象

2 投票
3 回答
1172 浏览
提问于 2025-04-16 07:41

我想在Django中创建一个对象,然后再调用保存方法。这个对象是根据一个外键值来创建的,我把外键字段改成了输入框,这样我就可以直接输入一个值,而不是从列表中选择。

我有两个类,分别在两个不同的模型文件里。

class Category(models.Model):
    title = models.ForeignKey(Title, verbose_name="Title")

还有

class Title(models.Model):
    title = models.CharField("Title", primary_key=True, max_length=200)

当我创建一个类别时,我必须选择或输入一个已经在数据库中的标题。如果我尝试用一个新的标题来创建类别,就会出现这个错误:

Select a valid choice. That choice is not one of the available choices.

我想做的是在创建类别之前,根据我在外键字段中输入的内容来创建一个标题,这样就可以立即使用。

我尝试重新定义保存方法,以便在保存类别之前先保存标题对象,但没有成功。

任何帮助都会非常感谢。

谢谢

3 个回答

1

谢谢你的代码,我刚刚测试了一下。但这并不是我想要的,我来解释一下我想做的事情。

假设我们在模型中有“类别”和“文章”这两个类,每个类都有一个标题。为了让这个标题可以重复使用,我创建了另一个应用来管理这些字段,我创建了一个“标题”类,并把它作为外键添加到“类别”和“文章”的表单中。

我把选择框换成了输入框,使用了raw_id_fields。

现在,当我创建一个类别或文章时,我必须选择或输入一个标题。当这个标题已经存在时,一切都很顺利,但如果这个标题不存在,我希望在创建类别之前先创建这个标题,这样它就可以使用了。

我尝试在保存方法、预保存信号和清理方法中实现这个功能,但总是出现错误:“选择一个有效的选项。这个选项不是可用选项之一。”

现在我使用了一个硬编码的解决方案来创建标题,我只是想看看它是否有效,这些是我在不同方法中插入的代码,用来在创建类别之前创建标题:

t = Title(title = "MyTitle")
t.save()

我尝试用“MyTitle”作为标题创建一个类别,但我得到了同样的错误。当我尝试使用一个已存在的标题创建另一个类别时,它就能成功,并且标题“MyTitle”也被创建了。这意味着对象的创建发生在表单验证之后。我想要的是在验证之前就创建这个标题对象。

非常感谢你的帮助。

1

在表单验证完成后,才会进行保存操作。你可以在验证的过程中创建分类对象。

可以查看一下表单字段的清理方法,这些方法可以被你重写,具体内容可以在Django文档中找到,链接是 http://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

-1

你可能需要考虑把创建分类的代码放在模型的管理器里:

class CategoryManager(Manager):
    def create_category(category, title):
        t = Title.objects.get_or_create(title=title)
        return self.create(title=t)

class Category(models.Model):
    title = models.ForeignKey(Title, verbose_name="Title")
    objects = CategoryManager()

然后每次想要创建一个分类的时候,就使用create_category这个方法。

撰写回答