Django模型-在另一个模型中从一行中选择的Charfield



我在Django中创建了一个设置表,如下所示:-

class Settings(models.Model):
name = models.CharField(max_length=200)
class Meta:
verbose_name = "Settings"
verbose_name_plural = "Settings"    
def __str__(self):
return self.name  
class SettingChoices(models.Model):   
setting = models.ForeignKey(Settings, on_delete=models.PROTECT) 
choice = models.CharField(max_length=200)    
class Meta:
verbose_name = "Setting Choices"
verbose_name_plural = "Setting Choices"    
def __str__(self):
return '{0} - {1}'.format(self.setting, self.choice)   

其示例用途为:-

Setting = Circuit Type:
Choices:
DSL
4G
Fibre

然后在另一个模型中,我希望能够将其作为一组选择

class Circuits(models.Model):
site_data = models.ForeignKey(SiteData, verbose_name="Site", on_delete=models.PROTECT)
order_no = models.CharField(max_length=200, verbose_name="Order No")
expected_install_date = models.DateField()
install_date = models.DateField(blank=True, null=True)
circuit_type = models.CharField(max_length=100, choices=*** here I would get model settings - Circuit Type - Choices ***)

目前,我在settings.py中使用列表,但它不灵活,我需要我的用户能够更改这些设置,而不是让我手动编辑settings.py中的列表,每次都会推送更改

我尝试了以下操作:

函数.py

def settings_circuit_types():
from home.models import SettingChoices
type_data = SettingChoices.objects.filter(setting__name='CIRCUIT_TYPES')
circuit_types = []
for c in type_data:
circuit_types.append(c.choice)
return circuit_types

型号.py

from app.functions import settings_circuit_types
CIRCUIT_CHOICES = settings_circuit_types()
...
circuit_type = models.CharField(max_length=100, choices= CIRCUIT_CHOICES)

但这引发了一个错误

dango.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

这是可以理解的,我想知道我试图通过其他方式实现的目标是否可能?

感谢

因此,正如我在评论部分提到的那样,这是一种更好的方法:

1-您不需要SettingsSettingChoices。它们基本上是相同的,所以你可以将它们组合成一个名为Setting:的模型

class Setting(models.Model):
name = models.CharField(max_length=200)
# if you need anything that you might think you need another model for,
# just think this way, add a BooleanField.
# for example if you have a setting available only for admins:
only_admin = models.BooleanField(default=False)
# then when you're going to make a from, just filter the options;
# options = setting.objects.filter(only_admin=False)
class Meta:
verbose_name = "Settings"
verbose_name_plural = "Settings"    
def __str__(self):
return self.name

2-对于Circuits模型,您只需要一个简单的ForeignKey字段:

class Circuits(models.Model):
site_data = models.ForeignKey(SiteData, verbose_name="Site", on_delete=models.PROTECT)
order_no = models.CharField(max_length=200, verbose_name="Order No")
expected_install_date = models.DateField()
install_date = models.DateField(blank=True, null=True)
circuit_type = models.ForeignKey(Setting, null=False, blank=False)

现在,当你想制作一个表格供用户填写时:

forms.py:

class CircuitsForm(forms.ModelForm):
class Meta:
model = Circuits
fields = ('install_date', 'circuit_type') # or other fields.
# and to filter which choices are available to choose from:
def __init__(self, *args, **kwargs):
super(CircuitsForm, self).__init__(*args, **kwargs)
self.fields["circuit_type"].queryset = setting.objects.filter(only_admin=False)

这样,您就有了一种安全、简单的方式来为用户和管理员制作表单。

你可以编辑管理面板本身,也可以用这样的表单为管理用户创建一个url。

此外,如果你不是那种使用django来呈现表单的人,你可以简单地在你的视图中获得可用的选项,并将其传递给模板,如下所示:

settings = setting.objects.filter(only_admin=False)

并在这样的模板中渲染:

<select name="circuit_type">
{% for setting in settings %}
<option value="{{ setting.pk }}">{{ setting.name }}</option>
{% endfor %}
</select>

现在,您将只有希望它们显示在表单中的选项,即使用户试图篡改模板代码并添加更多选项,表单也不会允许它们被接受,这将导致错误。

最新更新