我正在尝试模拟学习资源(书籍,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'
>>>
答案 0 :(得分:1)
感谢this blog post我能够按照建议使用ManyToManyField
来实现此功能。我必须说这篇博文比我在Django网站上发现的任何文档都要好。
MODEL:
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')
ADMIN:
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)
TEMPLATE:
{% for prereq in resource.prereqs.all %}
<li>{{ prereq.id }}</li>
{% endfor %}
答案 1 :(得分:0)
prereq_backlink
和prereq_resource
是管理员,因此对Resource
的访问权限如下:
r = Resource.objects.get(id=2)
for prereq in r.prereq_backlink.all():
print prereq.resource.title
但我加入@ daniel-roseman的问题:为什么你没有使用ManyToManyField
来完成这项任务?
class Resource(models.Model):
...
prereqs = models.ManyToManyField('self')