我有一些看起来像这样的数据:
Person | Favorite Color | Favorite Fruit
------------------------------------------
Bobby | RED | BANANA
Jared | YELLOW | RASPBERRY
Milly | BLACK | PEACH
Shawn | ORANGE | ORANGE
假设它处于flatfile,python dicts或其他非sql格式中。
编辑:假设为了论证,我已经在Python结构中得到了它,看起来像这样:
data = [
{"name": "Bobby", "favorite_color": "RED", "favorite_fruit": "BANANA"},
{"name": "Jared", "favorite_color": "YELLOW", "favorite_fruit": "RASPBERRY"},
# etc....
]
我的django模型看起来像这样:
class Person(models.Model):
COLORS = (
('R', 'RED'),
('O', 'ORANGE'),
('Y', 'YELLOW'),
('G', 'GREEN'),
('B', 'BLUE'),
('P', 'PURPLE'),
('L', 'BLACK'),
('W', 'WHITE')
)
name = CharField(max_length=256)
favorite_color = CharField(max_length=1, choices=COLORS)
favorite_fruit = ForeignKey(Fruit)
class Fruit(models.Model):
name = CharField(max_length=256)
fructose_content = PositiveIntegerField()
编辑:假设我的Fruit
模型已填充了所有可能的成果。
我想使用ModelForm
将我的数据从原始源导入到我的Django模型中,以利用正确的验证和数据库抽象。
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = '__all__'
ModelForm
是否可以将非规范化数据转换为可以保存在模型中的数据? ModelForm
在这里使用是错误的吗?
答案 0 :(得分:0)
请尝试以下代码:
setnames(DT, "0b", "something_digestible")
第一步是读取文件(假设它名为data.txt),我建议您使用json或其他一些结构化文本来避免输入错误,因为您可以先检查文件是否使用众所周知的格式良好库。
要使这个脚本起作用,你还需要一个表单中字段的技巧,我认为将PERSON字段称为NAME就足够了。
在第二步,我们为每个要插入的条目创建表单实例,验证它们,如果一切正常,我们将它们保存到数据库中。
希望它有所帮助,
答案 1 :(得分:0)
我提出了部分解决方案,至少对于涉及选择的问题。我想通过一些修补,它也适用于ForeignKey
字段。
首先,我定义一个函数get_choice_by_name
,它通过一个选择元组并按值查找键。
然后我将TypedChoiceField
子类化,并覆盖其clean()
方法以转换数据。在任何验证之前,似乎都会调用此方法。
以下是代码:
def get_choice_by_name(name, choices, case_sensitive=False):
try:
if name is None:
return ''
elif name and not case_sensitive:
return next(k for k, n in choices
if n.lower() == name.lower())
else:
return next(k for k, n in choices if n == name)
except StopIteration:
raise ValueError(
"Invalid choice: {}, not found in {}".format(name, choices)
)
class DenormalizedChoiceField(TypedChoiceField):
def clean(self, value):
if not value:
return self.empty_value
try:
value = get_choice_by_name(value, self.choices)
except ValueError as e:
raise ValidationError(str(e))
value = super(DenormalizedChoiceField, self).clean(value)
return value
我的ModelForm
现在只需要将相关字段重新定义为DenormalizedChoiceField
。我需要明确指定选项,但由于某些原因,如果覆盖该字段,它不会从模型中选择它。
class PersonForm(forms.ModelForm):
favorite_color = DenormalizedChoiceField(choices=Person.COLORS)
class Meta:
model = Person
fields = '__all__'