根据相同表单字段中所选项目的表单字段筛选选项django

时间:2016-02-06 14:57:00

标签: django django-models django-admin

我正在尝试为某种类型的游戏创建多种配置。

更新:

class GameType(models.Model):
    tag = model.CharField()
    name = model.CharField()

class GameConfig(models.Model):
    tag = model.CharField()
    game_type = model.ForeignKey('GameType')
    text_settings = model.ManyToManyField('GameTextSettings')
    levels_settings = model.ManyToManyField('GameLevelSettings')

class GameTextSettings(models.Model):
    tag = model.CharField()
    texts = ArrayField(models.CharField(max_length=maxLengthText), default=list, blank=True)

class GameLevelSettings(models.Model):
    tag = model.CharField()
    duration = models.IntegerField()

如果在创建新配置时,我可以强制用户先输入标签并选择类型,这将是非常好的。当他选择我希望给他选项的类型时,可以创建新的text_settings / level_settings,或者使用与另一个game_configuration相关联的text_settings / level_settings来获得相同的类型。

我认为我的数据库模型错了,但我对数据库的经验不足。我不想将GameLevelSettings或TextSettings直接链接到GameType,因为它们只应链接到GameConfiguration,但是我不知道如何实现这个'排序'在向用户呈现选择时。

你会建议什么?

谢谢

EDIT2:我的斗争是创建将实现我的逻辑的视图。我不知道如何以这种方式链接视图或如何根据从同一表单中提取的值过滤ModelChoiceFields选项。

额外信息:

方案: 所以基本上我想让用户为特定的GameType建立多个GameConfiguration。 GameConfigurations有一个GameLevelSettings数组和一个TextsSettings。我想让每个GameLevelSettings和TextsSettings都可以重复使用,这样当用户创建一个具有相同级别但不同文本的新GameConfiguration时,他可以重用已经定义的GameLevelSettings。

我如何形象这应该起作用

  1. 用户使用新的GameConfiguration创建表单打开页面(duuh:D)

  2. 在此表单上,用户可以选择(或创建)GameType并为新的GameConfiguration输入标签

  3. 一旦用户选择了GameType,就会向用户显示其他字段(TextsSettings和GameLevelSettings数组)的选项,或者能够创建新对象。这些字段的值已经过预过滤,因此只显示与用于相同GameType的其他(先前创建的)GameConfiguration相关联的对象。

  4. 具体方案:

    1. 我定义了3个游戏类型 - 蓝色,红色,绿色,并且已经为所有游戏配置创建了默认值的GameConfiguration。

    2. 现在我想为GameType Blue创建另一个GameConfiguration。

    3. 所以我打开创建视图并输入标签" Dark Blue"并选择GameType" Blue"来自下拉列表。

    4. 一旦我选择GameType,其他字段中的所有值都会被过滤,以便它们只显示与之前的Default Blue GameConfiguration相关联的对象,而与Red / Green GameConfigurations相关联的对象中没有显示 - 这基本上是为了让用户更容易搞乱并使用Red TextsSettings配置Blue GameType

    5. 希望这有帮助。

      干杯

1 个答案:

答案 0 :(得分:3)

django-smart-selects可以通过使用FK并渲染字段的JQuery脚本来根据表单中的其他选择进行过滤来实现此目的。

来自文档:

如果您有以下型号:

class Continent(models.Model):
        name = models.CharField(max_length=255)

class Country(models.Model):
        continent = models.ForeignKey(Continent)
        name = models.CharField(max_length=255)

class Location(models.Model):
    continent = models.ForeignKey(Continent)
    country = models.ForeignKey(Country)
    area = models.ForeignKey(Area)
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

您希望如果您选择一个大陆,只有位于该大陆的国家/地区可用,并且您可以执行以下操作:

from smart_selects.db_fields import ChainedForeignKey 

class Location(models.Model)
    continent = models.ForeignKey(Continent)
    country = ChainedForeignKey(
        Country, 
        chained_field="continent",
        chained_model_field="continent", 
        show_all=False, 
        auto_choose=True
    )
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

如果您希望从我暂时退回的页面中看到它,请查看Thermaline's BeerCalc并从左侧列中选择字段。

要知道的是,您可以使用现有模型上的智能选择的form_fields来过滤FK选择。在这种情况下,我有一个我的Material模型具有FK的现有模型ProductType。在我的大小调整表单中,当有人选择ProductType时,材料选择会相应地进行过滤。

from smart_selects.form_fields import ChainedModelChoiceField

# Arguments = ChainedModelChoiceField(app,model,to_field,modle_field,auto_select=False,show_all=False)

class SizingForm(forms.ModelForm):
    material = ChainedModelChoiceField('tubes', 'Material', 'product_type', 'product_type', False, False)