Django 选择表单来确定使用的类和字段



理想情况下,我希望在填写"类型"表单(现代/复古(后向用户显示两种表单,然后显示类中指定的字段属性。

我的 forms.py 目前看起来像这样,希望能更清楚地说明我所追求的是什么:

from django import forms
from .import models

class AddGame(forms.ModelForm):
class Meta:
model = models.Game
fields = ['name',
'type']
if type == 'Retro Game':
model = models.RetroGame
fields = ['name',
'type',
'platform',
'genre',
'slug',
'developer',
'rom',
'bios',
'emulator']
elif type == 'Modern Game':
model = models.ModernGame
fields = ['name',
'type',
'genre',
'publisher',
'slug',
'developer',
'online_play']

下面的代码是由用户 quqa123 为答案添加的。

像这样设置我的 models.py 文件样式会有什么问题?因此,有一个基类"游戏"继承了"表单"。模型窗体",然后是继承自类"游戏"的两个子类。这样,RetroGames 和 ModernGames 都共享基类中的属性。它们都有自己的列表,稍后我可以为每个列表添加一些其他唯一属性。

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Game(models.Model):

game_type = (
('MG', 'Modern'),
('RG', 'Retro'),
)
type = models.CharField(max_length=6, choices=game_type)
name = models.CharField(max_length=200)
genre = models.CharField(blank=True, max_length=100)
players = models.PositiveIntegerField(default=1)
publisher = models.CharField(blank=True, max_length=200)
developer = models.CharField(blank=True, max_length=200)
slug = models.SlugField()
date_added = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name

class RetroGame(Game):

game_platform = (
('PS1', 'PS1'),
('PS2', 'PS2'),
('XB', 'Xbox'),
('NES', 'Nintendo Entertainment System'),
)
platform = models.CharField(max_length=3, choices=game_platform)

class ModernGame(Game):

game_platform = (
('PC', 'PC'),
('PS4', 'PS4'),
('XB1', 'Xbox One'),
('NS', 'Nintendo Switch'),
)
platform = models.CharField(max_length=3, choices=game_platform)

如果我正确理解了您的代码,我认为您正在寻找的是数据库关系。您希望有一个将游戏添加到集合的表单,并且在表单中您可以选择它是复古游戏还是现代游戏,然后根据选择为其提供一些属性。为了使它在良好的编程实践中工作,您基本上创建了三个单独的模型(在您的 models.py 中( - 游戏,RetroGame和ModernGame,并且在它们内部,您可以在您的案例中建立一对一的数据库关系。更多信息: https://docs.djangoproject.com/en/3.0/topics/db/examples/one_to_one/

在这里,我将举例说明它是如何完成的:

class Game(models.Model):
name = models.CharField()
is_retro = models.BooleanField(default=False) # not a good practise
is_modern = models.BooleanField(default=False) # not a good practise
# some handling that when one is true other has to be false
# is needed here 
class RetroGame(models.Model):
# you dont need a name as Game already has it
game = models.OneToOneField(Game,on_delete=models.CASCADE)
type = models.CharField()
...
...

但说实话,你的代码真的很"混乱和肮脏",你应该以不同的方式设计你的应用程序 - 例如只制作RetroGame和ModernGame模型(省略游戏,因为它是多余的(。制作单独的ModelFroms并将它们呈现为隐藏到您的html中,并使用切换使其中一个可见,具体取决于用户是要添加现代游戏还是复古游戏。如果您有任何问题,请打我。

最新更新