我在使用外键,多对多字段或选择字段之间做出决定时遇到问题

时间:2016-11-26 06:23:52

标签: python django django-models django-admin

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

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

有游戏机(PC,Playstation 4等)和视频游戏(Rocket League,Minecraft等)。每个游戏必须至少在一个控制台上,但它可能更多。

我的想法是创建一个游戏控制台表,用于存储名称,徽标和其他有用信息。视频游戏桌将存储标题,封面,地图,游戏模式等。

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

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

models.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)

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

  

每个游戏必须至少在一个控制台上,但它可能是可用的   更多。

所以,'你好'可能会在PC'和' Playstation 4'和' World'可能只会运行PC'?这使得两个游戏机成为一个游戏' Hello',但两个游戏用于一个游戏机' PC'。这对我来说听起来像是一对多的关系。

答案 1 :(得分:1)

这里实际实现的是游戏机和视频游戏之间的多对多关系,而不使用Django的ManyToManyField。看起来似乎需要多对多的关系。

Game模型对应于'到' django的模特说话。但是您的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']

然后您可以使用Games Console来自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) 更改表格和副作品

  

如果要使用内联显示多对多关系,则可以   通过为关系定义InlineModelAdmin对象来实现:

"^(?:[A-Za-z0-9]+)( [A-Za-z0-9]*(?:\"[^\"]*\")*(?:\'[^\']*\')*[A-Za-z0-9]*)*&?$"