Задать вопрос
dkoldyaev
@dkoldyaev
Отличный парень!

Почему не отображаются Inline-объекты в плагинах django-cms?

Добрый день. Столкнулся с каким-то неадекватным поведением django-cms.

Описываю модель
# models.py

class Email(models.Model):
    email =         models.EmailField(blank=False, null=False, verbose_name=u'Электронная почта')
    order =         models.IntegerField(blank=False, null=False, default=0, verbose_name=u'Сортировка')
    contact_block = models.ForeignKey('contact.ContactBlockPlugin', related_name='emails', blank=False, null=False)
    def __unicode__(self):
        return self.email
    class Meta :
        ordering =  ['order',]

class ContactBlockPlugin(CMSPlugin):
    address =       models.TextField(blank=False, null=False, verbose_name=u'Адрес')


И регистрирую плагины, согласно документации (django-cms.readthedocs.org/en/latest/how_to/custom... )

# cms_plugins.py

class EmailInlineAdmin(admin.TabularInline):
    model = Email

class CMSContactBlockPlugin(CMSPluginBase):

    model =     ContactBlockPlugin
    module =    u'Контакты'
    name =      u'Контактный блок'

    render_template =   'contact/contact_block.html'

    inlines =   (EmailInlineAdmin, )

plugin_pool.register_plugin(CMSContactBlockPlugin)


Вроде все прекрасно… Я, как авторизованный пользователь, наполняю email'ы с фронтенда.
В шаблоне я спокойно итерируюсь по списку email'ов

{% if instance.emails.all|length > 0 %}
    <div class="b-contacts mail">
        {% for email in instance.emails.all %}
            <a href="mailto:{{ email.email }}">{{ email.email }}</a>
        {% endfor %}
    </div>
{% endif %}


Это если я авторизован. Но если я попытаюсь открыть эту страницу как гость (не залогинившись), то коллекция instance.emails.all оказывается пустой.

Я подозреваю, что дело в правах, но не могу понять, где их можно настроить для моих моделей.

Согласно документации, я попробовал переопределить функцию render как-то так

def render(self, context, instance, placeholder):
        context = super(CMSContactBlockPlugin, self).render(context, instance, placeholder)
        context.update({
            'emails':   instance.emails.all()
        })
        return context


и итерироваться так:

{% for email in emails %}
    <a href="mailto:{{ email.email }}">{{ email.email }}</a>
{% endfor %}


Но результат остался прежним.

Дебажил — просто пустая коллекция.
Что делать, ума не приложу.
  • Вопрос задан
  • 450 просмотров
Подписаться 3 Оценить 5 комментариев
Пригласить эксперта
Ответы на вопрос 1
kornov
@kornov
I'm a slice of a watermelon.
Если эта проблема Вам ещё интересна - вот выдержка из официальной документации:
Everytime the page with your custom plugin is published the plugin is copied. So if your custom plugin has foreign key (to it, or from it) or many-to-many relations you are responsible for copying those related objects, if required, whenever the CMS copies the plugin - it won’t do it for you automatically.


То есть Вам нужно определить метод (при определении модели), копирующий Ваши инлайны в новый инстанс.
Как то так:
class ContactBlockPlugin(CMSPlugin):
    address = models.TextField(blank=False, null=False, verbose_name=u'Адрес')

    def copy_relations(self, oldinstance):
        for associated_item in oldinstance.mails.all():
            associated_item.pk = None
            associated_item.contact_block = self
            associated_item.save()


Перечитайте внимательно отсюда - handling relations.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы