gpt4 book ai didi

python - Django admin - OneToOneField 内联抛出 "has no ForeignKey"异常

转载 作者:行者123 更新时间:2023-11-28 19:29:36 27 4
gpt4 key购买 nike

我有一个非常简单的应用程序,目前它声明了两个模型:一个称为“Content”,仅保存内容数据,另一个是“Page”,其中包含作为 OneToOneField 的“Content”。

我这样做的原因是我可以将“页面”作为我使用的实际具体类,当我计划的其他模块中的其他模型需要页面数据时,它们可以简单地将“内容”包含为一个 OneToOneField。我这样做是为了避免继承,而是使用组合。

模型.py:

from django.db import models

class Content(models.Model):
"""Basic page data which can be used by other modules"""
title = models.CharField(max_length=200)
html_title = models.CharField(max_length=200)
meta_desc = models.CharField(max_length=200)
keywords = models.CharField(max_length=200)
content = models.TextField()

class Page(models.Model):
"""Concrete implementation of a basic page managed by the admin"""
slug = models.SlugField()
content = models.OneToOneField(Content)

def __str__(self):
return self.content.title

管理员.py:

from django.contrib import admin
from content.models import Page, Content

class ContentInline(admin.TabularInline):
model = Content
fields = ('title', 'html_title', 'meta_desc', 'keywords', 'content')

class PageAdmin(admin.ModelAdmin):
fields = ('slug',)
inlines = [ContentInline]

在页面管理我得到这个异常:

Exception at /admin/content/page/add/
<class 'content.models.Content'> has no ForeignKey to <class 'content.models.Page'>

当然所说的是正确的,但我似乎无法找到一种方法来做我想做的事情,即包括关系的非定义端的内联。我不想在“内容”上声明关系,因为那时我必须在该类中定义与它的每一个关系,这会引入对其他模块的依赖关系,我认为它应该对此一无所知。

在 Python 3.3 上使用 Django 1.6。

编辑:如评论中所述,我决定使用继承。我最初对此的担忧是我希望能够灵活地从多个其他类中组合类。然而,由于 Django ORM 确实支持多重继承,而且如果我意识到该方法被称为“mixins”(Python 的新手),我会更快地到达某个地方。

与模型混合的示例:

from django.db import models

class Content(models.Model):
"""Basic page data which can be used by other modules"""
title = models.CharField(max_length=200)
html_title = models.CharField(max_length=200)
meta_desc = models.CharField(max_length=200)
keywords = models.CharField(max_length=200)
content = models.TextField()

def __str__(self):
return self.title

class Meta:
abstract = True

class Data(models.Model):
data_name = models.CharField(max_length=200)

class Meta:
abstract = True

class Page(Content, Data):
"""Concrete implementation of a basic page managed by the admin"""
slug = models.SlugField()

然后我可以在 admin.py 中将它用作一个模型。

最佳答案

另一种解决方案是将 OneToOneFieldContent 移动到 Page

class Content(models.Model):
"""Basic page data which can be used by other modules"""
title = models.CharField(max_length=200)
html_title = models.CharField(max_length=200)
meta_desc = models.CharField(max_length=200)
keywords = models.CharField(max_length=200)
content = models.TextField()
page = models.OneToOneField(Page, primary_key=True, related_name="content")

class Page(models.Model):
"""Concrete implementation of a basic page managed by the admin"""
slug = models.SlugField()

def __str__(self):
return self.content.title

您仍然可以执行 page.content 并且内嵌表单将开箱即用

编辑:

该方法的一个缺点是它允许用户创建页面而不向其分配任何内容(在这种情况下 page.content 将崩溃)

通过创建自定义表单很容易解决这个问题

class ContentAdminForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
kwargs["empty_permitted"] = False
super(ContentAdminForm, self).__init__(*args, **kwargs)

然后在管理页面

class ContentInline(admin.TabularInline):

model = Content
form = ContentAdminForm
fields = ('title', 'html_title', 'meta_desc', 'keywords', 'content')

关于python - Django admin - OneToOneField 内联抛出 "has no ForeignKey"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23305328/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com