2013-07-19 19 views
3

经过大量的搜索,只找到一些技术,这将允许我做到这一点(甚至更少的工作示例),我把它带给你。Django的管理员:允许ForeignKey的基类来引用其子类

以下是相似的类结构与我的工作:

# sources/models.py 
from django.db import models 

class Author(models.Model): 
    name = models.CharField(max_length=256) 
    slug = models.SlugField() 


class Source(models.Model): 
    author = models.ForeignKey(Author) 
    url = models.URLField(help_text='The URL where a copy of the source can be found.') 


class Book(Source): 
    title = models.CharField(max_length=256) 
    page = models.PositiveSmallIntegerField(help_text='Page where the source text appears.') 


class MagazineArticle(Source): 
    magazine_name = models.CharField(max_length=256) 
    issue_date = models.DateField() 
    title = models.CharField(max_length=256) 

而在一个单独的应用程序,我想有这样的:

# excerpts/models.py 
from django.db import models 
from sources.models import Source 

class Excerpt(models.Model): 
    excerpt = models.TextField() 
    source = models.ForeignKey(Source) 
    # Perhaps should be: 
    # source = models.OneToOneField(Source) 

美中不足之处在于在管理员中,我希望能够创建BookMagazineArticle作为摘录的来源,而不必在每个摘录中都有单独的字段。

我读过关于这样做可能工作的一种方法是泛型关系,可能使用抽象基类来代替,但我没有找到任何在我的上下文中有意义的示例。

什么是一些执行此方法(最好用例子)?

回答

0

任何一个都应该工作。这是你将如何与一个抽象基类做到这一点:

class Excerpt(models.Model): 
    excerpt = models.TextField() 
    source = models.ForeignKey(Source) 

    class Meta: 
     abstract = True 

class Book(Excerpt): 
    pass 
class Magazine(Excerpt): 
    pass 

现在你可以这样做:

book = Book.objects.all() 
magazine = Magazine.objects.filter(source=1) 
+1

我想你错误地理解了我的模型关系。书不是摘录,也不是杂志文章。这些是摘录的来源。摘录不应该是一个抽象类。如果有的话,Source可能是抽象的。 – radicalbiscuit

+0

@radicalbiscuit不认为它是真正的继承。将摘录视为[混合](http://stackoverflow.com/q/533631/1075247)。 – Pureferret

+0

@Pureferret确实,我理解这方面,但这个解决方案仍然不能解决我的问题(我很久没有重新讨论过了)。这种结构将每个'Book'或'Magazine'限制为一个片段,我期望能够将任意数量的片段分配给单个源。我将不得不再次看看我的问题。这已经很长时间了,我已经有了更多的练习,所以我可以制定一个可用的解决方案来解决我最初的担忧。 – radicalbiscuit

0

你的代码已经达到你想要的正确途径。 你有什么是多表继承。 Source拥有自己的表格,所有子类(Book,MagazineArticle)都有自己的表格。您创建的任何书籍或杂志都会自动在数据库端创建一个源文件;同时在引用子类模型时也表现为“具有额外字段的源”。 另请注意,一对一的字段是从子类到基类和基类到子类创建的。 这是管理员应该看起来如何:

# admin.py 
# imports go here... 
source = Source() 
source.save() 
excerpt1 = Excerpt(source=source) 
book = Book() 
book.save() 
except2 = Excerpt(source=book.source) # source=book may also work; haven't checked... 
book2 = excerpt2.source.book 
if book is book2: 
    except2.save() # only save this if my code is correct... 
相关问题