gpt4 book ai didi

python - 根据 Django 中先前的模型选择限制表单字段选择

转载 作者:太空宇宙 更新时间:2023-11-04 04:59:16 25 4
gpt4 key购买 nike

我目前正在尝试使用 Django 和 WoTC 提供的 SRD Material 创建 DnD 5e 角色创建器。这是我第一次使用 Django,我是边学边学的。几天来,我遇到了一些挑战,这些挑战让我陷入困境。我研究了这个问题,在应用了我认为可能有帮助的多种技术之后,我的运气有限。我的问题是:

我有许多代表英雄、种族、子种族、类(Class)、背景等的模型。我希望能够根据用户事先选择的种族来限制用户选择子种族的能力。到目前为止我有这个:

模型.py
class Race(models.Model):
race_name = models.CharField(max_length=200)
race_size = models.CharField(
max_length=2, choices=SIZE_CHOICE, default='M')
race_speed = models.IntegerField(
default=30)
race_lang = models.CharField(max_length=200, null=True, blank=True)
race_str = models.IntegerField(default=0, null=True, blank=True)
race_dex = models.IntegerField(default=0, null=True, blank=True)
race_con = models.IntegerField(default=0, null=True, blank=True)
race_int = models.IntegerField(default=0, null=True, blank=True)
race_wis = models.IntegerField(default=0, null=True, blank=True)
race_cha = models.IntegerField(default=0, null=True, blank=True)
skill_spend = models.IntegerField(default=0, null=True, blank=True)
race_extra = models.TextField(max_length=2000, blank=True, null=True)
race_source = models.CharField(max_length=200, blank=True)

def __str__(self):
return self.race_name

class Meta:
verbose_name = 'Race'
verbose_name_plural = 'Races'


class Subrace(models.Model):
sub_name = models.CharField(max_length=200)
sub_size = models.CharField(
max_length=2, choices=SIZE_CHOICE, default='M', null=True)
sub_speed = models.IntegerField(
default=30, null=True)
sub_lang = models.CharField(max_length=200, null=True, blank=True)
sub_str = models.IntegerField(default=0, null=True, blank=True)
sub_dex = models.IntegerField(default=0, null=True, blank=True)
sub_con = models.IntegerField(default=0, null=True, blank=True)
sub_int = models.IntegerField(default=0, null=True, blank=True)
sub_wis = models.IntegerField(default=0, null=True, blank=True)
sub_cha = models.IntegerField(default=0, null=True, blank=True)
sub_extra = models.TextField(max_length=2000, null=True, blank=True)
sub_parent = models.ForeignKey(Race, on_delete=models.CASCADE, null=True)

def __str__(self):
return self.sub_name

class Meta:
verbose_name = 'Subrace'
verbose_name_plural = 'Subraces'

class Hero(models.Model):

def roll_stats():
d6 = die.Dice(6)
list_stats = d6.roll(4)
list_stats.sort()
add = sum(list_stats[1:4])
return add

hero_name = models.CharField(max_length=200)
author = models.ForeignKey(User, null=True)
hero_subrace = models.ForeignKey(
Subrace, on_delete=models.CASCADE, null=True, blank=True)
pub_date = models.DateTimeField('date published', blank=True, null=True)
hero_klass = models.ForeignKey(Klass, on_delete=models.CASCADE, null=True)
hero_race = models.ForeignKey(Race, on_delete=models.CASCADE)
background = models.ForeignKey(
Background, on_delete=models.CASCADE, null=True)
health = models.IntegerField(blank=True, null=True)
hero_exp = models.IntegerField(default=0, null=True)
hero_alignment = models.ForeignKey(Alignment, blank=True, null=True)
hero_str = models.IntegerField(default=roll_stats, null=True, blank=True)
hero_dex = models.IntegerField(default=roll_stats, null=True, blank=True)
hero_con = models.IntegerField(default=roll_stats, null=True, blank=True)
hero_int = models.IntegerField(default=roll_stats, null=True, blank=True)
hero_wis = models.IntegerField(default=roll_stats, null=True, blank=True)
hero_cha = models.IntegerField(default=roll_stats, null=True, blank=True)

def save(self, *args, **kwargs):
"Returns a hero's hp"
die_str = str(self.hero_klass.hit_dice)
die_nums = die_str.split("d")
die_val = int(die_nums[1])
die_roll = int(die_nums[0])
hp_die = die.Dice(die_val)
results = hp_die.roll(die_roll)
self.health = sum(results)
super(Hero, self).save(*args, **kwargs)

def __str__(self):
return self.hero_name

def get_absolute_url(self):
return reverse('hero.views.detail', args=[str(self.id)])

class Meta:
verbose_name = 'Hero'
verbose_name_plural = 'Heroes'

View .py
def new_hero(request):
user = request.user
if request.method == "POST":
form = HeroForm(request.POST)
if form.is_valid():
hero = form.save(commit=False)
hero.author = request.user
hero.save()
return redirect('detail', hero.pk)
else:
form = HeroForm()
return render(request, 'new_hero.html', {'form': form, 'user': user})

表单.py
class HeroForm(forms.ModelForm):

class Meta:
model = Hero
fields = ['hero_name', 'hero_race', 'hero_subrace',
'hero_klass', 'hero_exp', 'health', 'background',
'hero_str', 'hero_dex', 'hero_con', 'hero_int',
'hero_wis', 'hero_cha', 'hero_alignment']

def __init__(self, *args, **kwargs):
super(HeroForm, self).__init__(*args, **kwargs)
for fieldname in ['hero_str', 'hero_dex', 'hero_con', 'hero_int', 'hero_wis', 'hero_cha']:
self.fields[fieldname].disabled = True
race = Race.objects.all()
for name in race:
self.fields['hero_subrace'].queryset = Subrace.objects.filter(sub_parent=name)

我尝试了几种不同的技术,但这就是我现在的处境。这个:

for name in race:
self.fields['hero_subrace'].queryset = Subrace.objects.filter(sub_parent=name)

是我最近添加到我的应用程序中的内容。在英雄创建屏幕上,我看到了一个空白的选择框,而不是没有循环或查询集的完整无限制列表。

基本上,我希望有人对我可能忽略的方法、我错过的或根本没有找到的方法提出一些建议。也请随意批评其余代码,就像我说这是我的第一个 Django 应用程序 :)。这也是我的第一个 Stack Overflow 问题,非常感谢 :)

最佳答案

对于任何想知道的人,我使用了 django-smart-selects解决我的问题。

base.html

<script type="text/javascript" src="{% static 'smart-selects/admin/js/chainedfk.js' %}"></script>
<script type="text/javascript" src="{% static 'smart-selects/admin/js/bindfields.js' %}"></script>

我将上面的 html 添加到我的 {% load staticfiles %} 调用中。

并更改了 models.py:

模型.py
from smart_selects.db_fields import ChainedForeignKey
class Hero(models.Model):
....
race = models.ForeignKey(Race, on_delete=models.CASCADE)
subrace = ChainedForeignKey(Subrace,
chained_field="race",
chained_model_field="race",
show_all=False,
auto_choose=True,
blank=True,
null=True)

现在我有一个 subrace 字段,它会在用户选择比赛时动态更新。

关于python - 根据 Django 中先前的模型选择限制表单字段选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46230686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com