直接在Django中获取和设置ForeignKey
我正在尝试使用Django模型,该模型是从一个mysql数据库创建的,该数据库具有复合外键 我的直接在Django中获取和设置ForeignKey,django,django-models,Django,Django Models,我正在尝试使用Django模型,该模型是从一个mysql数据库创建的,该数据库具有复合外键 我的models.py如下所示 class Make(models.Model): idmake = models.IntegerField(primary_key=True) make = models.CharField(max_length=20L, unique=True, blank=True) def __unicode__(self): return se
models.py
如下所示
class Make(models.Model):
idmake = models.IntegerField(primary_key=True)
make = models.CharField(max_length=20L, unique=True, blank=True)
def __unicode__(self):
return self.make
class Meta:
db_table = 'make'
class Models(models.Model):
idmodels = models.IntegerField(primary_key=True, unique=True)
make = models.ForeignKey(Make, db_column='make', to_field='make')
model = models.CharField(max_length=45L, unique=True)
resource_type = models.CharField(max_length=7L)
def __unicode__(self):
return self.model
class Meta:
db_table = 'models'
class Systems(models.Model):
idsystems = models.IntegerField(primary_key=True, unique=True)
make = models.ForeignKey(Models, null=True, db_column='make', blank=True, related_name='system_make')
model = models.ForeignKey(Models, null=True, db_column='model', to_field = 'model', blank=True, related_name='system_model')
serial_num = models.CharField(max_length=45L, blank=True)
service_tag = models.CharField(max_length=45L, blank=True)
mac = models.CharField(max_length=45L, unique=True)
现在,当我尝试访问系统的make
字段时,我得到一个ValueError
>>> s = Systems.objects.get(pk=1)
>>> s.model
<Models: model11>
>>> s.model.make
<Make: make1>
>>> s.make
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/django/db/models/fields/related.py", line 384, in __get__
rel_obj = qs.get(**params)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 395, in get
clone = self.filter(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 669, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 687, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1271, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1202, in add_filter
connector)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/where.py", line 71, in add
value = obj.prepare(lookup_type, value)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/where.py", line 339, in prepare
return self.field.get_prep_lookup(lookup_type, value)
File "/usr/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 1003, in get_prep_lookup
return super(IntegerField, self).get_prep_lookup(lookup_type, value)
File "/usr/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 322, in get_prep_lookup
return self.get_prep_value(value)
File "/usr/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 997, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'make1'
>s=Systems.objects.get(pk=1)
>>>美国模式
>>>美国制造
>>>美国制造
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python2.7/site packages/django/db/models/fields/related.py”,第384行,在__
rel_obj=qs.get(**参数)
get中第395行的文件“/usr/lib/python2.7/site packages/django/db/models/query.py”
clone=self.filter(*args,**kwargs)
过滤器中的文件“/usr/lib/python2.7/site packages/django/db/models/query.py”,第669行
返回self.\u filter\u或\u exclude(False、*args、**kwargs)
文件“/usr/lib/python2.7/site packages/django/db/models/query.py”,第687行,在“过滤器”或“排除”中
clone.query.add_q(q(*args,**kwargs))
文件“/usr/lib/python2.7/site packages/django/db/models/sql/query.py”,第1271行,在add_q中
can_reuse=使用的_别名,force_having=force_having)
文件“/usr/lib/python2.7/site packages/django/db/models/sql/query.py”,第1202行,在添加过滤器中
连接器)
文件“/usr/lib/python2.7/site packages/django/db/models/sql/where.py”,第71行,添加
值=对象准备(查找类型,值)
文件“/usr/lib/python2.7/site packages/django/db/models/sql/where.py”,第339行,在prepare中
返回self.field.get\u prep\u lookup(lookup\u类型,值)
文件“/usr/lib/python2.7/site packages/django/db/models/fields/____init__.py”,第1003行,在get_prep_查找中
返回super(IntegerField,self).get\u prep\u lookup(lookup\u type,value)
文件“/usr/lib/python2.7/site packages/django/db/models/fields/_init__.py”,第322行,在get_prep_查找中
返回self.get_prep_值(value)
文件“/usr/lib/python2.7/site packages/django/db/models/fields/_init__.py”,第997行,在get_prep_值中
返回int(值)
ValueError:基数为10的int()的文本无效:“make1”
我不允许更改数据库中的表和关系。我是Django的新手,我无法找出解决这个问题的正确方法。基本上,我希望能够直接获取和设置
系统
模型的make
字段。有人能告诉我该怎么做吗?我最初的想法是,我必须创建一个自定义的ForeignKey
字段 我怀疑您的代码与数据库架构不匹配。在这方面:
make = models.ForeignKey(Models, null=True, db_column='make', blank=True, related_name='system_make')
型号
应该是制造
,不是吗?而您的系统。模型
有to_field='model'
,您是否错过了to_field='make'
for系统。make
?我建议您删除整个数据库,运行syncdb
,然后再次创建测试数据。然后看看错误是否仍然发生
有关代码的更多提示:
-
<> L> > P>作为定义的<代码> toField=“模型”< /> >和<>代码> toField=“使”< /代码>,您最好考虑添加<代码> dByCalths= true<代码> > <代码> <代码> >代码>模型< /代码>字段。否则,当数据集很大时,查询性能可能会很差
- 如果要将
和Make.Make
设置为唯一和索引,则它们似乎被限定为主键。在您的情况下,Models.model
和idmake
真的有必要吗idmodels
保证唯一性primary\u key=True
是冗余的unique=True
- Django转换使用单数形式进行模型定义。即,使用
模型
,而不是系统
模型
。此外,我们通常使用系统
,而不是id
,idmake
。这些只是转换,由你决定idmodels
- 我发现了答案,这完全是偶然的。希望与面临类似问题的任何人分享。
直接从
系统访问make
>>> s = Systems.objects.get(pk=1)
>>> s.model
<Models: model11>
>>> s.model.make
<Make: make1>
>>> s.make_id
u'make1'
被警告。如果模型的get方法返回多个或不返回模型对象,则这将不起作用。例如,如果我的模型表如下所示:
然后
我觉得程序员需要对这些事情保持谨慎
编辑
从@ZZY的评论到这个答案和他自己的答案
class Models(models.Model):
idmodels = models.IntegerField(primary_key=True, unique=True)
make = models.ForeignKey(Make, db_column='make', to_field='make')
model = models.CharField(max_length=45L, unique=True)
resource_type = models.CharField(max_length=7L)
def __unicode__(self):
return self.model
class Meta:
db_table = 'models'
unique_together = ("make", "model")
此外,由于模型中的模型
字段是唯一的,因此我所描述的场景不应出现在正确的表格中谢谢您的回答@ZZY。我不完全理解你所说的模型
应该是制造
?在Models
表中,字段make
是一个外键,与make
表的make
字段相关。在系统中.make
我不能有to_field='make'
,因为make
在模型中不是唯一的。在Models
中,make
和model
一起是唯一的。如果需要make
和model
一起唯一,在class Meta
中,一起定义unique=(“make”,“model”)
<代码>对象。get
用于返回唯一的结果<代码>多个对象返回
和文本列表
在这种情况下不会完全按照预期工作。如果表中有多条具有相同查询值的记录,并且您希望获取第一条记录,请使用objects.filter(model='…').first()
。在您对模型
的定义中,模型
字段是唯一的。所以你的数据库不应该有重复的值
>>>> Models.objects.get(model='unknown').make.make
Traceback (most recent call last):
....
MultipleObjectsReturned: get() returned more than one Models -- it returned 2!
>>> Models.objects.get(model='not known').make.make
Traceback (most recent call last):
....
DoesNotExist: Models matching query does not exist.
class Models(models.Model):
idmodels = models.IntegerField(primary_key=True, unique=True)
make = models.ForeignKey(Make, db_column='make', to_field='make')
model = models.CharField(max_length=45L, unique=True)
resource_type = models.CharField(max_length=7L)
def __unicode__(self):
return self.model
class Meta:
db_table = 'models'
unique_together = ("make", "model")