python - 我无法决定是使用外键、多对多字段还是选择字段

标签 python django django-models django-admin

编辑:代码已使用工作解决方案更新

我正在构建一个视频游戏库,但在构建模型时遇到了一些问题。我不确定是否应该使用多对多、外键或选择字段来执行以下操作:

有游戏机(PC、Playstation 4 等)和视频游戏(火箭联盟、Minecraft 等)。每款游戏必须至少在一台主机上运行,​​但也可能在更多主机上运行。

我的想法是创建一个游戏控制台表来存储名称、 Logo 和其他有用信息。视频游戏表将存储标题、封面、 map 、游戏模式等。

理想情况下,用户可以在管理仪表板中编辑控制台信息或游戏。仪表板的游戏部分将允许编辑游戏及其可用的控制台。

这是我到目前为止所做的事情。

模型.py

class GameConsole(models.Model):
    name = models.CharField(
        max_length=8,
        default='PC',
    )

    # console_logo = models.ImageField()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'game console'
        verbose_name_plural = 'game consoles'
        db_table = 'console'
        ordering = ['-name']


class VideoGame(models.Model):
    title = models.CharField(
        max_length=128,
        default='???'
    )
    console = models.ManyToManyField(
        GameConsole,
    )

    # game_cover = models.ImageField()
    # company_website = models.URLField()
    # date_published = models.DateField()

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'video game'
        verbose_name_plural = 'video games'
        db_table = 'games'
        ordering = ['-title']

admin.py

 class ConsoleInline(admin.TabularInline):
    model = VideoGame.console.through


class GameConsoleAdmin(admin.ModelAdmin):
    list_display = ['name', ]


class VideoGameAdmin(admin.ModelAdmin):
    list_display = ['title', 'game_platform']
    inlines = [ConsoleInline]
    exclude = ('console',)

    def game_platform(self, obj):
        return ', '.join([item.name for item in obj.console.all()])


admin.site.register(GameConsole, GameConsoleAdmin)
admin.site.register(VideoGame, VideoGameAdmin)

预先感谢您的帮助!

最佳答案

您在这里实际实现的是控制台和视频游戏之间的多对多关系,而不使用 Django 的 ManyToManyField。看来这里确实需要多对多关系。

Game 模型对应于 django talk 中的“through”模型。但是您的 Game 模型没有任何附加字段,因此可以完全删除它,最终只剩下两个模型。

class GameConsole(models.Model):
    name = models.CharField(
        max_length=8,
        default='PC'
    )

    # console_logo = models.ImageField()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'game console'
        verbose_name_plural = 'game consoles'
        db_table = 'console'
        ordering = ['-name']


class VideoGame(models.Model):
    title = models.CharField(
        max_length=128,
        default='???'
    )
    consoles = models.ManyToManyField(Console)
    # game_cover = models.ImageField()
    # company_website = models.URLField()
    # date_published = models.DateField()

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'video game'
        verbose_name_plural = 'video games'
        db_table = 'games'
        ordering = ['-title']

那么您就可以使用 Admin InlinesConsoleGames 更改表单,反之亦然

If you want to display many-to-many relations using an inline, you can do so by defining an InlineModelAdmin object for the relationship:

class GameInline(admin.TabularInline):
     model = VideoGame
     exclude = ('consoles',)

class ConsoleInline(admin.TabularInline):
     model = Console

class GameConsoleAdmin(admin.ModelAdmin):
    list_display = ['name']
    inlines = [ GameInline]

class GameAdmin(admin.ModelAdmin):
    list_display = ['game', 'console']
    inlines = [ ConsoleInline, ]    

admin.site.register(GameConsole, GameConsoleAdmin)
admin.site.register(Game, GameAdmin)

关于python - 我无法决定是使用外键、多对多字段还是选择字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40815616/

相关文章:

python - django 中的语法错误

python - 将过滤器链接在一起

python - Django 中如何统计外键属性值

python - Numba:回退到对象模式时抑制错误

python - 使用 xml.etree.ElementTree 获取文件中的 XML 标签列表

python - Pandas 日期时间日频率到周频率

python - Django ORM : can I have a BooleanField associated to a char column in the database?

python - 优化Apply创建带有 bool 列的字符串列表

Pycharm 上的 Django : ImproperlyConfigured with DJANGO_SETTINGS_MODULE

Django最终用户定义的字段,如何?