Reputation: 441
I've been searching for an answer to this for a while. How can I add a field from one model to a related model and query the related models data.
Here is an example: One Person has many Jobs.
class Person(models.Model):
PersonId = models.AutoField(primary_key=True)
FirstName = models.CharField(max_length=200, default='')
LastName = models.CharField(max_length=200, default='')
class Job(models.Model):
JobId = models.AutoField(primary_key=True)
JobName = models.CharField(max_length=200, default='')
Person = models.ForeignKey(Person, db_column='PersonId')
def _fullname(self):
return self.Person.FirstName + " " + self.Person.LastName
fullname = property(_fullname)
The code above does work!
jobs = Job.objects.select_related()
for job in jobs:
print job.fullname
Now I think I have a different problem. Getting the Django Rest Framework to serialize these additional properties. Time for a new post.
Now what I want to be able to do is query jobs and get the related person data as well as have the person fields on the job. This way when I query jobs I can use job.FirstName. I basically want to make a shortcut to the Person fields from the Job. This is a bit like the Job is inheriting the fields of the Person.
An expected site effect of this would be when serializing the Job as json for a rest resource the result would include the Person field data.
I'm coming from a .Net C# background. Now since I'm using Python/Django I have no idea how to make this happen.
Upvotes: 1
Views: 914
Reputation: 6359
Try this out, it sounds like what you want.
Then a Job IS A Person, which, is what you're asking for. This is not abstract inheritance, so there will be two tables in your DB.
$> # This will dump the sql that's generated.
$> ./manage.py sql this_app
Job.FirstName will work. Read up on model inheritance. You might evenautally need to use django-model-utils's ModelInheritance manager, which is quite nice.
class Person(models.Model):
PersonId = models.AutoField(primary_key=True)
FirstName = models.CharField(max_length=200, default='')
LastName = models.CharField(max_length=200, default='')
class Job(Person):
JobId = models.AutoField(primary_key=True)
JobName = models.CharField(max_length=200, default='')
Upvotes: 0
Reputation: 594
Example of queryset which gets filtered list of Job objects:
joblist = Job.objects.filter(statement1,statement2...)
You can access to persons associated by ForeignKey with Job objects in this way
for j in joblist:
print j.Person.FirstName, j.Person.LastName
If you exactly need all related objects on every Job record you should use select_related queryset
joblist = Job.objects.select_related().filter(statement1,statement2...)
Serialization: You can use natural_keys, but it's limited with DB constraints. Or you can use Piston and define a Handler which will produce nested JSON.
Notice, you dont have to make AutoField for every model, it's specified by convention and can be reached at model_instance.id.
Also I recommend you to follow PEP8 conventions.
Upvotes: 1
Reputation: 19399
If you query your jobs with something like
job = Job.objects.get(personid=1)
you'll see that it pulls through the related fields too, it's voodoo behind the scenes. So essentially you can now do job.person.firstname
, job.person.lastname
etc...
Upvotes: 0