【问题标题】:how to send success message if we use django generic views如果我们使用 django 通用视图,如何发送成功消息
【发布时间】:2011-06-15 16:57:46
【问题描述】:

我是 django (1.2.4) 的新手。我用通用视图创建了一些杂物。但是,当使用 django 的消息传递框架创建学生时,如何显示“学生已成功添加”之类的内容?

【问题讨论】:

    标签: python django django-generic-views


    【解决方案1】:

    实际上,我认为文档很好地解释了基于通用/函数的视图: https://docs.djangoproject.com/en/2.0/ref/contrib/messages/

    它基本上使用 if 语句将上下文传递给您的模板以显示或不显示该上下文。

    查看:

    from django.contrib import messages
    def home_page(request):
        if request.method == 'POST':
            messages.success(request, 'Student added successfully')
            context = {}
            return render(request, 'homepage/index.html', context)
        else:
            form =yourForm()
            return render(request, 'homepage/index.html', form)
    

    然后它将使用以下内容显示在您的模板中。记住要迭代'...因为否则下一个请求将不会清除消息存储':

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

    当它再次呈现页面时,只需向您的表单添加一个锚标记并包含在您的表单操作中,即

    action="{% url 'home_page:index' %}#subscribe"
    

    如果您使用引导程序添加类alert-success

    【讨论】:

    • 如果我使用基于函数的视图如何实现?
    • 这是一个基于函数的视图...抱歉,关于基于类的视图不确定
    • 没问题,我从其他用户那里得到了答案。除deleteView之外的其他View,可以使用“SuccessMessageMixin”来实现。在 deleteView 中,这将帮助您实现。 stackoverflow.com/questions/62500284/…
    【解决方案2】:

    Django 1.6+ 开始,使用任何class-based generic views,您都可以依赖successMessageMixin。就像将 mixin 添加到您的类定义中并将 success_message 属性设置为您想要的任何内容一样简单。

    正如 Olivier Verdier 所说,请记住在您的主模板中使用display messages

    来自docs的一个简单例子:

    from django.contrib.messages.views import SuccessMessageMixin
    from django.views.generic.edit import CreateView
    from myapp.models import Author
    
    class AuthorCreate(SuccessMessageMixin, CreateView):
        model = Author
        success_url = '/success/'
        success_message = "%(name)s was created successfully"
    

    一个更复杂的例子:

    from django.contrib.messages.views import SuccessMessageMixin
    from django.views.generic.edit import CreateView
    from myapp.models import ComplicatedModel
    
    class ComplicatedCreate(SuccessMessageMixin, CreateView):
        model = ComplicatedModel
        success_url = '/success/'
        success_message = "%(calculated_field)s was created successfully"
    
        def get_success_message(self, cleaned_data):
            #  cleaned_data is the cleaned data from the form which is used for string formatting
            return self.success_message % dict(cleaned_data,
                                               calculated_field=self.object.calculated_field)
    

    【讨论】:

      【解决方案3】:

      您要求的功能已在 Django 通用视图中实现:

      https://github.com/django/django/blob/1.2.X/django/views/generic/create_update.py#L115

      您将在主模板中看到displaying messages 的消息。

      【讨论】:

      • 你们很多人想更新这个答案中的 URL,链接已经死了
      【解决方案4】:

      据我所知,使用传统的通用视图并没有直接的方法。我一直觉得关于通用视图的文档非常缺乏,因此从未使用它们。

      理论上,您可以通过假设重定向意味着成功提交来使用装饰器。

      所以你可以写这样的东西(这些代码都没有经过测试):

      urls.py

      try:
          from functools import wraps
      except ImportError:
          from django.utils.functional import wraps
      from django.http import HttpRedirectResponse
      from django.contrib import messages
      from django.views.generic import * 
      
      def add_message(success_message=None):
          def decorator(func):
              def inner(request, *args, **kwargs):
                  resp = func(request, *args, **kwargs)
                  if isinstance(resp, HttpRedirectResponse):
                      messages.success(request, message)
                  return resp
              return wraps(func)(inner)
          return decorator
      
      
      
      student_info_edit = {
        'template_name': 'myapp/student/form.html',
        'template_object_name': 'student',
        'form_class':  studentForm,
      }
      
      student_info_new = {
        'template_name': 'myapp/student/form.html',
        'form_class':  studentForm,
        'post_save_redirect': '/myapp/students/',
      }
      
      urlpatterns += patterns('',
        url(r'^students/$', list_detail.object_list, { 'queryset': Student.objects.all() }, name="students"),
        url(r'^students/(?P<object_id>\d+)/$', add_message("Student record updated successfully")(create_update.update_object), student_info_edit, name="student_detail"),
        url(r'^students/new$', add_message("The student was added successfully.")(create_update.create_object), student_info_new, name="student_new"),
      )
      

      说了这么多,Django 1.3 引入了class-based generic views,所以如果你对迁移到 Django 1.3 感兴趣,你应该研究一下。他们可能允许更多的自定义,不确定。

      从长远来看,我很少看到使用通用视图的好处形式,这对于添加/更新之类的东西来说是双倍的。

      【讨论】:

      • 谢谢,我决定不使用通用视图,因为它不够灵活,无法处理实际场景。
      • 我接受这个答案,因为它对我做出决定有很大帮助(对于其他人:我还没有测试过代码)
      • +1。不错的解决方案!你是装饰者肯定应该包含在消息模块中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-12
      • 2020-05-13
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      相关资源
      最近更新 更多