Django:如何继承和查询相关字段

发布于 2024-11-27 21:54:57 字数 1067 浏览 1 评论 0原文

一段时间以来我一直在寻找这个问题的答案。如何将一个模型中的字段添加到相关模型并查询相关模型数据。

这是一个例子:一个人有很多工作。

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)

上面的代码确实有效!

jobs = Job.objects.select_related()
for job in jobs:
    print job.fullname

现在我想我有一个不同的问题。让 Django Rest Framework 序列化这些附加属性。是时候发表新帖子了。

现在我想要做的是查询职位并获取相关人员数据以及职位上的人员字段。这样,当我查询职位时,我可以使用 job.FirstName。我基本上想从工作中创建到人员字段的快捷方式。这有点像 Job 继承了 Person 的字段。

预期的站点效果是,当将 Job 序列化为剩余资源的 json 时,结果将包括 Person 字段数据。

我有 .Net C# 背景。现在,由于我使用 Python/Django,我不知道如何实现这一点。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断肠人 2024-12-04 21:54:57

获取 Job 对象过滤列表的查询集示例:

joblist = Job.objects.filter(statement1,statement2...)

您可以访问由 ForeignKey 与 Job 对象以这种方式

for j in joblist:    
    print j.Person.FirstName, j.Person.LastName

如果您确实需要每个 Job 记录上的所有相关对象,您应该使用 select_lated 查询集

joblist = Job.objects.select_related().filter(statement1,statement2...)

序列化:
您可以使用 natural_keys,但它受到数据库约束的限制。或者您可以使用 Piston 并定义一个将生成嵌套 JSON 的处理程序。

请注意,您不必为每个模型创建 AutoField,它是按约定指定的,并且可以通过 model_instance.id 访问。

另外,我建议您遵循 PEP8 约定。

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.

琉璃梦幻 2024-12-04 21:54:57

如果你用类似的方式查询你的工作
job = Job.objects.get(personid=1) 你会看到它也提取了相关字段,这是幕后的巫术。所以本质上你现在可以做 job.person.firstname, job.person.lastname 等等...

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...

北方的韩爷 2024-12-04 21:54:57

尝试一下,这听起来就是你想要的。

那么工作就是一个人,这就是您所要求的。这不是抽象继承,因此您的数据库中将有两个表。

gt; # This will dump the sql that's generated.
gt; ./manage.py sql this_app

Job.FirstName 会起作用。阅读模型继承。您甚至可能需要使用 django-model-utils 的 ModelInheritance 管理器,这非常好。

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='')

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.

gt; # This will dump the sql that's generated.
gt; ./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='')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文