【问题标题】:Create an object before calling the save method在调用 save 方法之前创建一个对象
【发布时间】:2010-11-27 18:50:45
【问题描述】:

我想在调用 save 方法之前在 Django 中创建一个对象。该对象将从 ForeignKey 值创建,我已将外键字段更改为看起来像输入字段以便写入值而不是选择它。

我在 2 个不同的模型文件中有 2 个类

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.

我想做的是在创建类别之前根据我在 ForeignKey 字段中写入的内容创建一个标题,以便可以立即使用它。

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

任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    表单验证后进行保存,可以在验证过程中创建类别obj。

    查看可以在 django 文档http://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other 上覆盖的表单字段的干净方法

    【讨论】:

    • 表单验证不适合创建模型。
    • @Ignacio 请针对这种情况提出更好的替代方案
    【解决方案2】:

    感谢您的代码,我刚刚测试过了。但这并不是我想要的,我会解释我想要做什么。

    假设我们的模型中有 Category 和 Article 类,每个类都有一个标题。为了使这个标题可重用,我创建了另一个管理字段的应用程序,我创建了 Title 类并将其作为外键添加到 Category 和 Article 表单。

    我使用 raw_id_fields 将选择框切换到输入字段。

    现在,当我创建一个类别或一篇文章时,我必须选择或编写一个标题,当这个标题存在时,它可以完美地工作,但当它不存在时,我想在创建类别之前创建它,这样它就可以使用它。

    我尝试在 save 方法、pre_save 信号和 clean 方法中执行此操作,但我总是收到错误消息“选择一个有效的选择。该选择不是可用的选择之一。”

    我现在正在使用硬编码的解决方案来创建标题,我只是想看看它是否会起作用,这些是我在创建类别之前在不同的方法中插入的用于创建标题的行:

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

    我尝试创建一个以 MyTitle 作为标题的类别,但我遇到了同样的错误,当我尝试使用现有标题创建另一个类别时,它可以正常工作并创建标题“MyTitle”。这意味着对象的创建发生在表单验证之后。我想要的只是以前这样做。标题对象应在验证前创建。

    非常感谢您的帮助

    【讨论】:

      【解决方案3】:

      您可能应该考虑将用于创建类别条目的代码放在模型的管理器中:

      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。

      【讨论】:

      • 感谢您的回答。我应该在哪里调用 create_category 方法?以及如何设置它的属性?
      • 验证表单数据后,从视图中调用 create_category,如下所示:create_category("a new category", "a new or existing title")。我没有正确理解你的问题吗?
      • 我想在管理表单中这样做。标题应该在类别之前创建,以便它可以使用它。我试图覆盖 pre_save 信号并创建一个我在保存类别时使用的标题,但我没有工作。我认为 ForeignKey 检查发生在发送 pre_save 信号之前。有办法改变它或禁用外键验证吗?谢谢
      • 好的,在这种情况下,您可以考虑重新设计模型。如果您想要将标题分配给类别并能够重用标题模型,则可以使用 contenttypes 框架和管理员的通用内联使标题指向类别。我在这里写了一个(未经测试的)示例:pastebin.com/kwDe3WNf。另请参阅文档docs.djangoproject.com/en/dev/ref/contrib/admin/…
      • 非常感谢。请检查下面的答案,我已经详细解释了我想要什么
      猜你喜欢
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      • 2012-12-28
      • 2023-02-14
      • 1970-01-01
      相关资源
      最近更新 更多