gpt4 book ai didi

python - 如何使用对任意数量的任意字段类型的引用来建模对象? (django orm)

转载 作者:行者123 更新时间:2023-11-28 18:55:59 25 4
gpt4 key购买 nike

我想定义一组模型/对象,允许一个代表关系:field_set 有许多字段,其中字段是 django.db.model 字段对象(IPAddressField、FilePathField 等)。

我的目标是拥有一个支持以下类型的“api”的 ORM 模型。

从 Controller 的角度来看:

# Desired api below
def homepage(request):
from mymodels.models import ProfileGroup, FieldSet, Field

group = ProfileGroup()
group.name = 'Profile Information'
group.save()

geographicFieldSet = FieldSet()
# Bind this 'field set' to the 'profile group'
geographicFieldSet.profilegroup = group
address_field = Field()
address_field.name = 'Street Address'
address_field.f = models.CharField(max_length=100)
# Bind this field to the geo field set
address_field.fieldset = geographicFieldSet

town_field = Field()
town_field.name = 'Town / City'
town_field.f = models.CharField(max_length=100)
# Bind this field to the geo field set
town_field.fieldset = geographicFieldSet

demographicFieldSet = FieldSet()
demographicFieldSet.profilegroup = group
age_field = Field()
age_field.name = 'Age'
age_field.f = models.IntegerField()
# Bind this field to the demo field set
age_field.fieldset = demographicFieldSet

# Define a 'weight_field' here similar to 'age' above.

for obj in [geographicFieldSet, town_field, address_field,
demographicFieldSet, age_field, weight_field]:
obj.save()


# Id also add some methods to these model objects so that they
# know how to render themselves on the page...

return render_to_response('page.templ', {'profile_group':group})

从本质上讲,我想支持“逻辑分组的字段”,因为我认为自己支持许多不同类型的“字段集”,因此我希望进行有意义的抽象。

我想定义这个模型,这样我就可以定义一组字段,其中字段的数量和字段类型都是任意的。所以我可能有一个字段组“地理”,其中包括字段“州”(带选择的 CharField)、“城镇”(TextField)等。

这是我到目前为止的想法:

class ProfileGroup(models.Model):
name = models.CharField(max_length=200)

# FieldSets have many Fields
class FieldSet(models.Model):
name = models.CharField(max_length=200)
profilegroup = models.ForeignKey(ProfileGroup)

class Field(models.Model):
f = models.Field()
fieldset = models.ForeignKey(FieldSet)

虽然使用这些模型会在 shell 中产生错误,并且最终不允许我存储任意字段。

In [1]: from splink.profile_accumulator.models import Field, FieldSet, ProfileGroup
In [2]: import django.db
In [3]: profile_group = ProfileGroup()
In [4]: profile_group.name = 'profile group name'
In [5]: profile_group.save()
In [6]: field_set = FieldSet()
In [7]: field_set.name = 'field set name'
In [8]: field_set.profilegroup = profile_group
In [9]: field_set.save()
In [10]: field = Field()
In [11]: field.name = 'field name'
In [12]: field.f = django.db.models.FileField()
In [13]: field.save()
---------------------------------------------------------------------------
ProgrammingError Traceback (most recent call last)

/var/www/splinkpage.com/splinkpage.pinax/splink/<ipython console> in <module>()

/usr/lib/pymodules/python2.5/django/db/models/base.pyc in save(self, force_insert, force_update)
309 raise ValueError("Cannot force both insert and updating in "
310 "model saving.")
--> 311 self.save_base(force_insert=force_insert, force_update=force_update)
312
313 save.alters_data = True

/usr/lib/pymodules/python2.5/django/db/models/base.pyc in save_base(self, raw, cls, force_insert, force_update)
381 if values:
382 # Create a new record.
--> 383 result = manager._insert(values, return_id=update_pk)
384 else:
385 # Create a new record with defaults for everything.

/usr/lib/pymodules/python2.5/django/db/models/manager.pyc in _insert(self, values, **kwargs)
136
137 def _insert(self, values, **kwargs):
--> 138 return insert_query(self.model, values, **kwargs)
139
140 def _update(self, values, **kwargs):

/usr/lib/pymodules/python2.5/django/db/models/query.pyc in insert_query(model, values, return_id, raw_values)
890 part of the public API.
891 """
892 query = sql.InsertQuery(model, connection)
893 query.insert_values(values, raw_values)
--> 894 return query.execute_sql(return_id)

/usr/lib/pymodules/python2.5/django/db/models/sql/subqueries.pyc in execute_sql(self, return_id)
307
308 def execute_sql(self, return_id=False):
--> 309 cursor = super(InsertQuery, self).execute_sql(None)
310 if return_id:
311 return self.connection.ops.last_insert_id(cursor,

/usr/lib/pymodules/python2.5/django/db/models/sql/query.pyc in execute_sql(self, result_type)
1732
1733 cursor = self.connection.cursor()
-> 1734 cursor.execute(sql, params)
1735
1736 if not result_type:

/usr/lib/pymodules/python2.5/django/db/backends/util.pyc in execute(self, sql, params)
17 start = time()
18 try:
---> 19 return self.cursor.execute(sql, params)
20 finally:
21 stop = time()

ProgrammingError: can't adapt

所以我想知道这是否是完全错误的方法,或者我是否需要稍微不同地使用 django 的模型类来获得我想要的东西。

最佳答案

我看到代码有几个问题。首先,使用此类定义:

class Field(models.Model):
f = models.Field()
fieldset = models.ForeignKey(FieldSet)

类 models.Field 不应该直接用于字段定义。它是 Django 中所有字段类型的基类,因此它缺乏对特定字段类型有用的细节。

第二个问题是以下行:

In [12]: field.f = django.db.models.FileField()

当您分配给 Field 实例的属性 f 时,您应该提供一个特定的值以保存到数据库中。例如,如果您使用 CharField 来定义 Field.f,您将在此处分配一个字符串。 models.Field 虽然没有特定的可分配值。您正在尝试分配显然无法保存到数据库的内容。它是 modles.FileField 定义。

因此,Django 很难“调整”您分配给字段属性的值,原因有二。首先,没有为要分配的 models.Field 类型定义值,因为它是一个“抽象类”,或者是特定字段类型定义的基类。其次,您不能将“字段定义”分配给属性并希望将其保存到数据库中。

我理解你的困惑。从数据库和 Django 的角度来看,您基本上是在尝试做不可能的事情。

不过,我想您的设计问题可能有解决方案。如果您详细描述了您想要实现的目标,有人可能会给您提示。

关于python - 如何使用对任意数量的任意字段类型的引用来建模对象? (django orm),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1107024/

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