Помогите с пониманием родовых отношений в Django (и их использование в Admin)
Я создаю 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 ответа
Как 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() будет всеми связанными элементами.
Кроме того, скобки не используются в синтаксисе шаблона.
Почему вы пытаетесь получить доступ link.content_object
внутри page.link.all()
список? Внутри этого списка link.content_object
всегда будет таким же, как page
,
Я не думаю, что я понимаю, что вы пытаетесь сделать здесь, но сейчас этот код должен генерировать список ссылок на текущую страницу с link.title
текст.
Можете ли вы объяснить, что вы пытаетесь сделать с LinkedItem
?
Я не видел шаблоны доступа к менеджерам напрямую, как при использовании 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>
увидеть
Я бы дал больше ссылок, но стек не позволил бы мне.