A
A
Andrey Kovalchuk2017-02-25 08:55:05
Django
Andrey Kovalchuk, 2017-02-25 08:55:05

Django + ajax What is the right way to reload objects?

Good day.

What is: the page on which objects are unloaded, here is its fragment (I give the section for convenience):

index.html

<section>
            <!-- Latest news title -->
            <div class="wrap wrap_white">
                <div class="container title">
                    <h1 class="title__h1 underscore">Latest news</h1>
                </div>
            </div>
            <!-- END Latest news title -->
            <div class="wrap wrap_gray pt20">
                <div class="container">
                    <div class="row">
                        {% for news in news_items_list %}
                            {% if forloop.counter == 1 %}
                                <div class="col-sm-6">
                                    <div class="thumbnail thumbnail_big">
                                        <img src="{{ news.image.url }}" height="350" width="560" alt="News">
                                        <div class="caption thumbnail__caption">
                                            <div class="news caption__news">
                                                <p class="news__category yellow-line">{{ news.category }}</p>
                                                <a href="{% url 'mainApp:detail_news' news.id %}" class="news__head">{{ news.title }}</a>
                                                <p class="news__desc"> {{ news.content | truncatechars:360  }}</p>
                                            </div>
                                            <div class="posted">
                                                <span class="posted__date"><i class="icon-clock-1"></i> {{ news.date }}</span>
                                                <ul class="posted__icon">
                                                    <li>
                                                        <span>
                                                        <i class="icon-comment-empty"></i>29
                                                    </span>
                                                    </li>
                                                    <li>
                                                        <span>
                                                        <i class="icon-eye"></i>2.3k
                                                    </span>
                                                    </li>
                                                </ul>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            {% else %}
                                {% include 'mainApp/inc-news_block-sm3.html' %}
                            {% endif %}

                        {% endfor %}


                    </div>
                </div>
                <!-- Btn load-->

                <div class="ajax_load">
                    <i class="icon-arrows-cw"></i>Load more
                    <svg width="128" height="40" viewBox="0 0 128 40" xmlns="http://www.w3.org/2000/svg">
                        <rect x='0' y='0' fill='none' width='128' height='40'></rect>
                    </svg>
                </div>
                <!-- END Btn load-->
            </div>
            <!-- /Container-->
        </section>


Here is inc-news_block-sm3.html:

<div class="col-sm-3">
    <div class="thumbnail thumbnail_small">
        <a href="{% url 'mainApp:detail_news' news.id %}" class="thumbnail__link">
            <img src="{{ news.image.url }}" height="153" width="270" alt="News">
        </a>
        <div class="caption thumbnail__caption">
            <div class="news caption__news">
                <p class="news__category yellow-line">{{ news.category }}</p>
                <a href="{% url 'mainApp:detail_news' news.id %}" class="news__link">
                    <p class="news__text">{{ news.title | truncatechars:63}}</p>
                </a>
            </div>
            <div class="posted">
                <span class="posted__date"><i class="icon-clock-1"></i>{{ news.date }}</span>
                <ul class="posted__icon">
                    <li>
                        <span>
                            <i class="icon-comment-empty"></i>11
                        </span>
                    </li>
                    <li>
                        <span>
                            <i class="icon-eye"></i>1.1k
                        </span>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>


What you need: so that when you click on Load More, 4 more elements are thrown by Ajax.

Here is a sketch of the function that handles the ajax request:
View.py
def more_news(request):
    tmp = IndexView.count_news
    if request.is_ajax():
        objects = News.objects.order_by('-date')[tmp:tmp + 4]
        html = loader.render_to_string('mainApp/inc-news_block-sm3.html', {'news': objects}, request=request)
        data = {'errors': False, 'html': html}
        try:
            tmp += 4
            return JsonResponse(data)
        except News.DoesNotExist:
            return JsonResponse({'errors': 'Something happened'})
    raise Http404


I understand the principles of interaction between Ajax and views (more/less), but I cannot understand the logic of a particular situation. I see two solutions:
1. Reload the entire section with an extended set of objects
2. Draw 4-8 more objects.

On the first approach, there is one question: is it correct? Logically, no. Load more hard, not refresh.

There are more questions about the second approach:
- It turns out that we need to make several, additional, invisible rows that we will draw? Or somehow it is possible to generate them in the right place?
- How to store the current number of downloaded objects? I tried to implement it in the view, but I feel it will not work.
- In line 5 of view.py I use loader. And here is the problem: since I need to draw the first object separately, the additional template starts working from the second object and it will not work to transfer all objects to it, because the loop is initialized elsewhere, and 1 object is passed there. To transfer all objects to this template, you need to integrate the cycle there, but then what about the first element? Nested loop with if that will ignore the first circle? So will it be right?

In general, please help to resolve these issues.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question