具有多个关系的Django数据库和ForeignKeys

时间:2015-07-28 19:08:20

标签: python django database

我有多个不同关系的数据库,我无法弄清楚如何正确构建事物以避免Django Admin出现问题。

这是我想要的设计:

Category
 -> 'name'       (CharField)

Movie
 -> Multiple CharFields

CategoryLink
 -> 'category'   (ForeignKey -> Category)
 -> 'movie'      (ForeignKey -> Movie)
 -> 'prefix'     (ForeignKey -> Prefix) - Blank, Null
 -> 'number'     (DecimalField)

Prefix
 -> 'category'   (ForeignKey -> Category)
 -> 'prefix'     (CharField)

我想实现的是一个结构:

  • 每个类别可以有多个分类链接到电影
  • 电影可以在任意数量的类别中存在任意次。
  • CategoryLinks可以有一个前缀,但不必有一个。
  • 前缀仅限于特定类别
  • 编辑特定类别的前缀不会影响不同类别的同名前缀
  • 类别可以包含多个或零个前缀
  • 如果Prefix.category == CategoryLink.category
  • ,前缀只能由CategoryLink使用
  • 不相关的前缀在类别
  • 中隐藏

我的主要问题是,当我尝试将前缀的选择限制为仅显示与当前类别相关的选项时,我会碰壁。我可以在编辑CategoryLink时做得很好,但在添加新的时却没有。

如果我尝试使用以下内容限制管理面板中的选项:

#admin.py
# ....
def __init__(self, *args, **kwargs):
    super(PrefixForm, self).__init__(*args, **kwargs)
    Prefix.objects.filter(category_id=self.instance.category.id)

编辑时工作正常,但只要我处于能够添加新条目的表单中,就会抛出错误。由于新条目没有已定义的category.id(我假设)不存在但Django在我处抛出“RelatedObjectDoesNotExist”异常。

如果我可以在编辑现有类别时使其正常工作。我不需要在没有类别的情况下创建新的CategoryLinks,但是当我尝试时我得到相同的错误,因为我使用TabularInline类将CategoryLinks包含到Category中。

我愿意完全重组一切以使其发挥作用,因为你可能会说我是Django的新手,所以我可能会想到这一切都错了。

上周我问了一个类似的问题,我以为自己已经想到了,但事实证明我只是把问题推了一步而不是解决它。

有没有更好的方法来构建我的模型,或者我可以在admin.py中做些什么来正确过滤前缀到类别?如果你想查看我的所有代码,请告诉我,在这里发帖似乎有点太多了。

我可以通过将CategoryLink.prefix转换为CharField来“解决”这个问题,但如果我可以为前缀设置一个单独的模型,它会更加凉爽。

这是我完整的Model.py(减去一些不相关的__unicode__内容)

from django.db import models


class Category(models.Model):
    class Meta:
        verbose_name_plural = "Categories"

    name = models.CharField(max_length=255, unique=True)

    def category_link_count(self):
        return len(CategoryLink.objects.filter(category_id=self.id))

    category_link_count.short_description = 'Movies in Category'


class Movie(models.Model):
    title = models.CharField(verbose_name='Movie Title', max_length=300)
    year = models.DecimalField(verbose_name='Year of Release',
                 max_digits=4, decimal_places=0)

class CategoryLink(models.Model):
    class Meta:
        verbose_name = "Category Link"
        verbose_name_plural = "Category Links"

    category = models.ForeignKey(Category)
    movie = models.ForeignKey(Movie)
    prefix = models.ForeignKey('Prefix', blank=True, null=True)
    number = models.DecimalField(verbose_name='Movie Number', max_digits=2,
                                 blank=True, null=True, decimal_places=0)


class Prefix(models.Model):
    category = models.ForeignKey(Category)
    prefix = models.CharField(verbose_name='Category Prefix', max_length=255)

    class Meta:
        verbose_name = "Prefix"
        verbose_name_plural = "Prefixes"
        ordering = ['-category']

1 个答案:

答案 0 :(得分:0)

我的建议是为与其他模型有关系的字段设置默认值,这样您就可以创建一个Category并具有任意Prefix。但是,我认为您已经不恰当地构建了模型。

Category有一个到Prefix的ManyToManyField,其FK为Category。你不需要FK。这只是一个,但您可以真正简化您的组织。我不太了解你想要完成的事情。