how to send success message if we use django generic views
Asked Answered
F

4

18

I am new to django (1.2.4). I have created some crud with generic views. But How can I show something like "The student was added successfully" when student is created using django's messaging framework?

Fineable answered 26/1, 2011 at 8:19 Comment(0)
S
4

As far as I know, there isn't a straightforward way of doing this using traditional generic views. I've always felt that the documentation on generic views was pretty lacking and so never used them.

In theory you could use a decorator by making the assumption that a redirect meant a successful submission.

So you could write something like this (none of this code has been tested):

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"),
)

All that said and coded, Django 1.3 introduced class-based generic views, so if you're interested in moving onto Django 1.3 you should look into those. They may allow more customization, not sure.

In the long run I rarely see the benefit form using generic views, and this goes double for things like add/update.

Shoulders answered 26/1, 2011 at 9:22 Comment(3)
Thanks, I have decided not to use generic view, as it is not flexible enough to handle practical scenarios.Fineable
I am accepting this answer as it helped me a lot in making my decision ( for others: I haven't tested the code yet )Fineable
+1. Nice solution! You're decorator should surely be included in the messages module.Bodgie
S
46

As of Django 1.6+, using any class-based generic views, you can rely on the successMessageMixin. It's as simple as adding the mixin to your class definition and setting success_message attribute to whatever you want.

As Olivier Verdier mentioned, please remember to display messages in your main template!

a simple example from the 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"

a more complex example:

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)
Spies answered 6/2, 2014 at 10:10 Comment(0)
S
4

As far as I know, there isn't a straightforward way of doing this using traditional generic views. I've always felt that the documentation on generic views was pretty lacking and so never used them.

In theory you could use a decorator by making the assumption that a redirect meant a successful submission.

So you could write something like this (none of this code has been tested):

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"),
)

All that said and coded, Django 1.3 introduced class-based generic views, so if you're interested in moving onto Django 1.3 you should look into those. They may allow more customization, not sure.

In the long run I rarely see the benefit form using generic views, and this goes double for things like add/update.

Shoulders answered 26/1, 2011 at 9:22 Comment(3)
Thanks, I have decided not to use generic view, as it is not flexible enough to handle practical scenarios.Fineable
I am accepting this answer as it helped me a lot in making my decision ( for others: I haven't tested the code yet )Fineable
+1. Nice solution! You're decorator should surely be included in the messages module.Bodgie
C
2

The functionality that you are asking for is already implemented in Django generic views:

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

You will see the messages by displaying messages in your main template.

Conscientious answered 3/4, 2011 at 7:59 Comment(1)
You many want to update the URLs in this answer, the links are deadBatsman
M
0

Actually I think the documents explain it pretty well for generic/function based views: https://docs.djangoproject.com/en/2.0/ref/contrib/messages/

It basically passes context to your template with an if statement to display that context or not.

View:

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)

And then it will be displayed in your template using the following. Remember to iterate '...because otherwise the message storage will not be cleared for the next request':

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

As it renders the page again just add an anchor tag to your form and include in your form action i.e.

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

If you're using bootstrap add class alert-success

Mentality answered 30/5, 2018 at 10:51 Comment(3)
How to implement if i'm using Function based view?Gish
This is a function based view... Sorry not sure with regards to class based viewMentality
No issues, i got the answer from the fellow user. Other Views than deleteView, it can be achieved by using "SuccessMessageMixin". In deleteView, this will help you to achieve. #62500784Gish

© 2022 - 2024 — McMap. All rights reserved.