通过Djang中的关系访问完整对象

2024-04-25 20:20:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试模拟学习资源(书籍、DVD等)和什么 这些资源具备的先决条件。你知道吗

先决条件也是资源。所以我的问题是,什么Django 建模技术最能体现这种关系?学习资源是 直截了当:

from django.db import models
from django.utils import timezone

class Resource(models.Model):
    title = models.CharField(max_length=300)
    shortcode = models.CharField(max_length=20, null=True, blank=True)
    img = models.URLField(null=True, blank=True)
    summary = models.TextField(null=True, blank=True)
    url = models.URLField('Link to Resource', null=True, blank=True)
    pub_date = models.DateTimeField('date published')

    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

    def __unicode__(self):
        return self.title

然而,我不确定用什么样的“最佳”方式来建模 前提条件,假设它也是一个Resource,最重要的是有一个可变数量的前提条件(这样就消除了简单地拥有一个自我参照的父母的可能性)。以下是我目前的做法:

class Prereq(models.Model):
    prereq = models.ForeignKey(Resource, null=True, related_name='prereq_backlink')
    resource = models.ForeignKey(Resource, null=True, related_name='prereq_resource')

    def __unicode__(self):
        return self.resource.title

这种方法的问题是,访问一个先决条件 没有给我一个完整的资源对象,所以我无法访问 其各个字段(标题、快捷码等):

schemelab@schemelab2:~/domains/org/metaperl/tmp/idhhb/django/mysite$ ./manage.py shell
>>> from idhhb.models import Resource, Prereq
from idhhb.models import Resource, Prereq
>>> p = Resource.objects.get(id=2)
>>> p.title
u'American Book of the Dead'
>>> r = Resource.objects.get(id=2)
r = Resource.objects.get(id=2)
>>> p1 = r.prereq_backlink
>>> p2 = r.prereq_resource
>>> p1
<django.db.models.fields.related.RelatedManager object at 0x2e279d0>
>>> p2
<django.db.models.fields.related.RelatedManager object at 0x2e27a90>
>>> p1.title
p1.title
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'RelatedManager' object has no attribute 'title'

>>> p2.title
p2.title
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'RelatedManager' object has no attribute 'title'
>>> 

Tags: djangofromimportselftruetitlemodels资源
2条回答

多亏了this blog post,我能够按照建议使用ManyToManyField来实现这一点。我必须说这篇博文比我在Django网站上找到的任何文档都要好。你知道吗

型号:

class Resource(models.Model):
    title = models.CharField(max_length=300)
    shortcode = models.CharField(max_length=20, null=True, blank=True)
    img = models.URLField(null=True, blank=True)
    summary = models.TextField(null=True, blank=True)
    url = models.URLField('Link to Resource', null=True, blank=True)
    pub_date = models.DateTimeField('date published')
    prereqs = models.ManyToManyField(
        'self', through='Prereq', symmetrical=False, related_name='prerequired')

    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

    def __unicode__(self):
        return self.title

class Prereq(models.Model):
    resource = models.ForeignKey(Resource, null=True, related_name='main_resource')
    prereq = models.ForeignKey(Resource, null=True, related_name='prereq_resource')

管理员:

from django.contrib import admin
from idhhb.models import Resource, Prereq

class PrereqInline(admin.TabularInline):
    model = Prereq
    fk_name = 'resource'
    extra = 5

class ResourceAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': 'title shortcode img summary url pub_date'.split() }),
    ]
    inlines = [PrereqInline,]


admin.site.register(Resource, ResourceAdmin)

模板:

{% for prereq in resource.prereqs.all %}
    <li>{{ prereq.id }}</li>
{% endfor %}

prereq_backlinkprereq_resource是管理器,因此对Resource的访问如下所示:

r = Resource.objects.get(id=2)
for prereq in r.prereq_backlink.all():
    print prereq.resource.title

但我也加入了@danielroseman的问题:为什么你不使用ManyToManyField来完成这个任务?你知道吗

class Resource(models.Model):
    ...
    prereqs = models.ManyToManyField('self')

相关问题 更多 >