Niveous
Niveous

Reputation: 105

Call an object's method from Django's Template on click

What I have currently is:

<ul>
    {% for object in object_list %}
        <li>
            <ul>
                <li>{{ object.property1}}</li>
                <li>{{ object.property2}}</li>
            </ul>
        </li>
    {% endfor %}
</ul>

What I want to do is call a method (which would be {{ object.remove }}) if, and only if, the user presses the remove button. I need to use one of the object's properties in the remove method, so it has to be that specific object's remove() call.

I know how to call a function inside the view, as there are many questions about that, but I'm not sure how that will help? Same with AJAX calls.

Upvotes: 1

Views: 1781

Answers (2)

Mikhail Kashkin
Mikhail Kashkin

Reputation: 1538

You need to get object from database, usually by id that you get from URL and do your call.

For example you have a Post with this line in url.py:

urlpatterns = patterns('',
    url(r'^(?P<post_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<post_id>\d+)/remove/$', views.remove, name='remove'),
    # ...
)

Then you have views.py:

from .models import Post

def detail(request, post_id):
    try:
        post = Post.objects.get(pk=question_id)
    except Post.DoesNotExist:
        raise Http404("Error 404")
    return render(request, 'detail.html', {'post': post})

def remove(request, post_id):
    try:
        post = Post.objects.get(pk=question_id)
        post.remove()
    except Post.DoesNotExist:
        raise Http404("Error 404")
    return render(request, 'confirm.html', {'message': 'Post was removed'})

And in your template add link to remove view:

<ul>
{% for post in post_list %}
    <li>
        <ul>
            <li><a href="/{{ post.id }}/remove/">{{ post.id}}</a></li>
            <!-- or add AJAX call to this URL -->
        </ul>
    </li>
{% endfor %}
</ul> 

That is how you usually deal with it in Django.

As long as post_id is just an function parameter you can use it as index id for your own stored list or dictionary. But make sure that your regexp in urls.py rules apply to your needs. In my example r'^(?P<post_id>\d+)/remove/$' looks for integers (because of \d+ rule). More information in Django Documentation

Upvotes: 2

Anentropic
Anentropic

Reputation: 33863

You need to think about how a website works...

  1. The browser sends a request to your web server for a particular url
  2. Your web server passes the request details to your Django application
  3. Django looks in your urlconf to find a view matching that url
  4. Django calls the url function (or method of view class) with a request object
  5. The view code renders a template, producing a string of HTML
  6. The web server sends the HTML back to the user's browser

So, with this in mind, it's clear that the only way to interact with Django when the user clicks a button on the web page is for the browser to send a new request.

In short, you need to use AJAX.

Upvotes: 1

Related Questions