【问题标题】:Django 1.8: Message in Class-Based View Not DisplayedDjango 1.8:基于类的视图中的消息未显示
【发布时间】:2015-11-29 12:31:53
【问题描述】:

我正在使用 Django 1.8.6 (Python 3.5.0) 编写一个简单的网站来提供租赁服务。用户创建租用后(使用基于类的CreateView),用户将被重定向到应显示“成功”消息的租用索引页面(索引模板继承自base.html)。

我阅读了 Django 的 messages framework 的文档和 adding messages in class-based views 的相关部分。

我将相关部分添加到我的代码中,但创建租金后,该消息未显示。 <div id="messages">(来自 base.html)以 HTML 呈现,但不显示消息(因为 success_message 未在 RentCreateView 中处理)。

我的设置:

settings.py(根据文档,Django 1.8 不需要额外设置):

...
INSTALLED_APPS = (
    ...
    'django.contrib.sessions',
    'django.contrib.messages',
    'rental_service',
)
...
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    ...
)
...
TEMPLATES = [
     {
        ...
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
     },
]

base.html(遍历消息):

...
<div id="messages">
    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}
</div>
...

rent_list.html(扩展 base.html):

{% extends "base.html" %}
...

views.py(使用 SuccessMessageMixin 提供的 success_message 属性):

class RentCreateView(CreateView, SuccessMessageMixin):
    model = Rent
    fields = [
        "timestamp_rent",
        "timestamp_return",
        "customer",
        "rental_examples"
    ]
    template_name_suffix = "_create_form"
    success_message = "Rent created successfully." # Ignored: even if "def get_success_message(self, cleaned_data): raise Exception()"

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(RentCreateView, self).form_valid(form)

    def get_success_url(self):
        return reverse("rental_service:rent_index")

【问题讨论】:

  • 翻转继承顺序,即(SuccessMessageMixin, CreateView)SuccessMessageMixin 覆盖 form_valid() 并且您会遇到 CreateView 的菱形继承问题。
  • 我注意到为时已晚:它——当然——不是钻石继承。 CreateView 继承 FormMixinFormMixin.is_valid() 是死路一条。因此出现了 MRO 问题。

标签: python django


【解决方案1】:

感谢dhke由于方法解析顺序问题为我指明了正确的方向。

翻转继承顺序解决问题:

views.py:

class RentCreateView(SuccessMessageMixin, CreateView):
    ...

顺便说一句:当adding messages in class-based views 时,基类的顺序很重要。

【讨论】:

  • 对于任何(可能)覆盖基类功能的 Mixin,顺序实际上很重要。将基类放在首位然后是 Mixins 似乎很自然,因为 mixins “仅”add 功能(它对我有用)。当然,这通常是错误的方式。
猜你喜欢
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-04
  • 2017-04-27
  • 2020-10-11
  • 2016-03-06
相关资源
最近更新 更多