Помогите с пониманием родовых отношений в Django (и их использование в Admin) - PullRequest
0 голосов
/ 02 апреля 2010

Я создаю 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>

Очевидно, что я чего-то не знаю или неправильно понимаю, но я чувствую, что иду в ту область, где я не знаю, чего не знаю. Чего мне не хватает?

Ответы [ 3 ]

1 голос
/ 02 апреля 2010

Как LinkedItem ассоциируется с Page? GenericRelation используется для обратных отношений, но в настоящее время нет никаких отношений, поэтому ему нечего сопоставлять. Я думаю, это то, что вы ищете в своей модели:

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)

Примечание: эта модель позволяет одному LinkedItem относиться к Page. Если вы хотите повторно использовать связанные элементы, вы можете сделать его 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 () будет всеми связанными элементами.

Кроме того, скобки не используются в синтаксисе шаблона.

0 голосов
/ 02 апреля 2010

Почему вы пытаетесь получить доступ к link.content_object в списке page.link.all()? Внутри этого списка link.content_object всегда будет таким же, как page.

Не думаю, что я понимаю, что вы пытаетесь сделать здесь, но сейчас этот код должен сгенерировать список всех ссылок на текущую страницу с текстом link.title.

Можете ли вы объяснить, что вы пытаетесь сделать с LinkedItem?

0 голосов
/ 02 апреля 2010

Я не видел шаблонов доступа к менеджерам напрямую, как при использовании page.links.all

Насколько я понимаю, вам нужно извлечь ссылки в виде списка в представлении и передать его в качестве переменной в шаблон. Кроме того, вам необходимо заранее разрешить все внешние ключи, что можно сделать с помощью select_related.

т.

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>

см.

Я бы дал больше ссылок, но стек не позволил бы мне.

...