0

我正在为我公司的网站构建一个 CMS(我已经查看了现有的 Django 解决方案,并且想要一些更苗条/更简单的东西,并且可以专门处理我们的情况。另外,我想更好地学习这些东西)。我很难理解泛型关系。

我有一个Page模型、一个SoftwareModule模型和一些其他模型来定义我们网站上的内容,每个模型都有自己的get_absolute_url()定义。我希望我的用户能够为任何Page实例分配任何类型的对象列表,包括其他页面实例。该列表将成为该Page实例的子菜单。

我尝试了以下方法:

class Page(models.Model):
    body = models.TextField()
    links = generic.GenericRelation("LinkedItem")

    @models.permalink
    def get_absolute_url(self):
        # returns the right URL

class LinkedItem(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    title = models.CharField(max_length=100)

    def __unicode__(self):
        return self.title

class SoftwareModule(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        # returns the right URL

这让我有了一个与 API 的通用关系来做page_instance.links.all()。我们正在路上。我不确定如何完成,是在页面实例的更改表单上,如何创建该页面与数据库中任何其他现存对象之间的关系。我想要的最终结果:在模板中呈现以下内容:

<ul>
{% for link in page.links.all %}
    <li><a href='{{ link.content_object.get_absolute_url() }}'>{{ link.title }}</a></li>
{% endfor%}
</ul>

显然,有些事情我没有意识到或误解,但我觉得我正在踏入那个我不知道我不知道什么的领域。我错过了什么?

4

3 回答 3

1

LinkedItem与 a 有什么关系Page?AGenericRelation用于反向关系,但就目前而言,没有任何关系,因此它没有可匹配的内容。我认为这是您在模型设计中寻找的内容:

class Page(models.Model):
    body = models.TextField()
    # Moved generic relation to below

class LinkedItem(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    # LinkedItems now relate to a Page model, and we're establishing the relationship
    # by specifying 'links' to keep the syntax you're looking for
    page = models.ForeignKey(Page, related_name='links')

    title = models.CharField(max_length=100)

附带说明一下,此模型设置允许LinkedItemPage. 如果你想重用linkeditems,你可以把它变成一个M2M:

class Page(models.Model):
    body = models.TextField()
    links = models.ManyToManyField(LinkedItem)

class LinkedItem(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    title = models.CharField(max_length=100)

在这两种情况下, page.links.all() 将是所有链接的项目。

此外,模板语法中不使用括号。

于 2010-04-02T19:39:55.707 回答
0

在使用 page.links.all 之前,我没有直接看到模板访问管理器

据我了解,您需要将链接作为视图中的列表拉回,并将其作为变量传递给模板。此外,您需要提前解析任何外键,这可以通过使用 select_related 来完成。

IE。

def some_view(request,*args,**kwargs):

  ...
  page_links = page_instace.links.select_related().all()
  ...

  return render_to_response(
                'the_template.html',
                #extra_context to pass to the template as var_name:value
                {
                    "page_links":page_links,
                },
                # needed if you need access to session variables like user info
                context_instance=RequestContext(request)
            )

然后在模板中...

<ul>
{% for link in page_links %}
    <li><a href='{{ link.content_object.get_absolute_url() }}'>{{ link.title }}</a></li>
{% endfor%}
</ul>

我会提供更多链接,但堆栈不会让我。

于 2010-04-02T17:12:33.637 回答
0

您为什么要尝试访问列表link.content_object中的内容page.link.all()?在此列表中,link.content_object将始终与 相同page

我认为我不明白您在这里要做什么,但是现在该代码应该生成一个链接列表,所有链接都指向带有link.title文本的当前页面。

你能解释一下你想做LinkedItem什么吗?

于 2010-04-02T19:36:46.960 回答