Reputation: 4068
I have a question about this error and hope someone has ran into it like I have. I am getting this error on a model when trying to use the Models.ForeignKey field. I can verify that the table the foreign key is used in exists, as well as the table that the fk references exists. I can get the model to work if I use a CharField but that is no fun.
Here are the tables(using Postgresql 9.0) I did not design so please don't rag on me too much if you do not like it, although I cannot guarantee I would have designed it any better:
Claim_status
Column | Type | Modifiers
-----------------+-----------------------------+------------------------------------------------------------------------
claim_no | character varying(30) | not null
claim_status | character varying(15) |
userid | character varying(40) | not null
note | character varying(255) |
time | timestamp without time zone | default now()
claim_status_id | integer | not null default nextval('claim_status_claim_status_id_seq'::regclass)
Indexes:
"claim_status_pkey" PRIMARY KEY, btree (claim_status_id)
"ndx_claim_status_claim_no" btree (claim_no) CLUSTER
"ndx_claim_status_claim_status" btree (claim_status)
"ndx_claim_status_date_time" btree (date("time"))
"ndx_claim_status_time" btree ("time")
"ndx_claim_status_upper_userid" btree (upper(userid::text))
"ndx_claim_status_userid" btree (userid)
Foreign-key constraints:
"$1" FOREIGN KEY (claim_status) REFERENCES lk_claim_status(claim_status)
"claim_status_claim_no_fkey" FOREIGN KEY (claim_no) REFERENCES claim(claim_no) ON UPDATE CASCADE
lk_claim_status
Column | Type | Modifiers
----------------------+-----------------------+---------------
claim_status | character varying(15) | not null
description_internal | character varying(35) | not null
description_web | character varying(35) | not null
display_insured_web | boolean | default false
display_rep_web | boolean | default false
Indexes:
"lk_claim_status_pkey" PRIMARY KEY, btree (claim_status)
Referenced by:
TABLE "claim_status" CONSTRAINT "$1" FOREIGN KEY (claim_status) REFERENCES lk_claim_status(claim_status)
My models:
from django.db import models
from test.django.common.models.claim.lk_claim_status import LkClaimStatus
class ClaimStatus(models.Model):
claim_no = models.CharField(max_length=40)
# the foreign key does not work here, you get matching query error for some reason.
claim_status = models.ForeignKey(LkClaimStatus, db_column='claim_status')
#claim_status = models.CharField(max_length=15)
userid = models.CharField(max_length=40)
note = models.CharField(max_length=255)
time = models.DateTimeField(auto_now=True)
claim_status_id = models.AutoField(primary_key=True)
class Meta:
db_table = u'claim_status'
-- end claim_status.py -- start lk_claim_status.py
from django.db import models
class LkClaimStatus(models.Model):
claim_status = models.CharField(max_length=15, primary_key=True)
description_internal = models.CharField(max_length=35)
description_web = models.CharField(max_length=35)
display_insured_web = models.BooleanField()
display_rep_web = models.BooleanField()
class Meta:
db_table = u'lk_claim_status'
I have not used in any pages yet but have just tested them out with the manage.py shell
Here have been my tests
from test.django.common.models.claim.claim_status import ClaimStatus
from test.django.common.models.claim.lk_claim_status import LkClaimStatus
status_list = ClaimStatus.objects.filter(claim_no='TEST')
for status in status_list:
try:
print status.claim_status.claim_status
except LkClaimStatus.DoesNotExist:
print "Got a blank one"
That last test prints out nothing but the except print statement. If I use the CharField option from the ClaimStatus model I can print a status.claim_status and get a value from the db table.
from test.django.common.models.claim.claim_status import ClaimStatus
from test.django.common.models.claim.lk_claim_status import LkClaimStatus
status_list = ClaimStatus.objects.filter(claim_no='TEST')
for status in status_list:
print status.claim_status.claim_status
With the above test I get this:
>>> for status in status_list:
... print status.claim_status.claim_status
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
File "/usr/lib/python2.5/site-packages/django/db/models/fields/related.py", line 315, in __get__
rel_obj = QuerySet(self.field.rel.to).using(db).get(**params)
File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 349, in get
% self.model._meta.object_name)
DoesNotExist: LkClaimStatus matching query does not exist.
I would understand this if the table did not exist or the fields did not exist, but they do? I can verify as well that with the test there are no null values for that claim_status field in either table.
Upvotes: 1
Views: 1281
Reputation: 174748
You need to do database introspection (also called reflection), which will create the appropriate django classes for you. In django terminology, this is called inspection
Once you have got your settings.py
with the appropriate db settings, run this command:
python manage.py inspectdb > models.py
This should give you a better django mapping of your database and allow you to run your queries.
Upvotes: 0
Reputation: 335
I can definitely see one problem with your models here. When you define a ForegnKey field with the name "claim_status", Django will be automatically creating an attribute on your model instances called "claim_status_id" which will be used to store the raw value of the "claim_status" database column. However, you already have a primary key field with the same name, which probably leads to a conflict.
I am not sure what is the official way of solving this problem, but you could try to subclass ForeignKey and override its get_attname() method to return something else.
Upvotes: 2