我正在尝试使用从具有复合外键的mysql数据库创建的Django模型。
我的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'
我不允许更改数据库中的表和关系。我是Django的新手,我无法弄清楚这个问题的正确解决方法是什么。基本上我希望能够直接获取并设置make
模型的Systems
字段。有人可以指导我如何去做这件事吗?我最初的想法是,我必须创建一个自定义ForeignKey
字段。
答案 0 :(得分:0)
我怀疑您的代码与您的数据库架构不符。在这一行:
make = models.ForeignKey(Models, null=True, db_column='make', blank=True, related_name='system_make')
Models
应该是Make
,不是吗?而您的Systems.model
已to_field = 'model'
,您是否错过to_field='make'
Systems.make
?我建议您删除整个数据库,运行syncdb
并再次创建测试数据。然后看看错误是否仍然存在。
您的代码的其他一些提示:
作为您定义的to_field = 'model'
和to_field='make'
,您最好考虑为db_index=True
和make
字段添加model
。否则,当数据集很大时,查询性能可能会很差
如果您要将Make.make
和Models.model
设置为唯一且已建立索引,则它们似乎被限定为主键。您的案例中idmake
和idmodels
是否真的有必要?
primary_key=True
保证唯一。 unique=True
是多余的
Django转换使用单数形式进行模型定义。即,使用Model
System
,而不是Models
Systems
。另外,通常我们使用id
,而不是idmake
,idmodels
。这些只是转换,由您决定
答案 1 :(得分:0)
我发现了答案,而不是偶然。想与任何面临类似问题的人分享。
直接从make
Systems
>>> s = Systems.objects.get(pk=1)
>>> s.model
<Models: model11>
>>> s.model.make
<Make: make1>
>>> s.make_id
u'make1'
直接从make
对象
Systems
>>> s.make_id = Models.objects.get(model='model21').make.make
>>> s.save()
>>> s.make_id
u'make2'
警告。如果Models的get方法返回多个或没有模型对象,则这将不起作用。例如,如果我的Models
表格如下:
然后
>>>> 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.
我认为程序员需要对这些事情保持谨慎。
修改强> 从@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")
由于model
中的Models
字段是唯一的,因此我描述的方案不应出现在正确的表格中