-3

I am getting data from the server. The view must renders an html page without reloading the entire page، but this renders whole page including the header of current page, this is a problem, each time request to the server to get the data

Here is the HTML that the server send with fetch when i click on button

{% for post in posts %}
    <div class="posts-item">
        {{post.description|linebreaks|truncatewords:20}}
        Published at {{post.created}} by {{post.author}}
        <br>
        {% for tag in post.tag.all %}
            <a href="{% url 'social:post_list_by_tag' tag.slug %}">{{tag.name}}</a>
            {% if forloop.last %}, {% endif %}
        {% endfor %}
        <a href="{% url 'social:post_detail' post.pk %}">post details</a>
        <hr><br>
    </div>
{% endfor %}

Here is the current page, posts-list.html:

{% extends 'parent/base.html' %}
{% block title%} posts list {% endblock %}
{% block content %}

<div class="posts">
    {% for post in posts %}
        {{post.description|linebreaks|truncatewords:20}}
        Published at {{post.created}} by {{post.author}}
        <br>
        {% for tag in post.tag.all %}
            <a href="{% url 'social:post_list_by_tag' tag.slug %}">{{tag.name}}</a>
            {% if forloop.last %}, {% endif %}
        {% endfor %}
        <a href="{% url 'social:post_detail' post.pk %}">post details</a>
        <hr><br>
    {% endfor %}
</div>

<button class="load-more">load more</button>
<script>
    var page = 2;
    function loadMore(){
        var url = '{% if tag_slug %}{% url "post_list_by_tag" tag.slug %}{% else %}{% url "social:post_list" %}{% endif %}'+'?page='+page;
        fetch(url, {
            method: 'GET',
            headers: {
                'content-type': 'text/html', 'x-requested-with': 'XMLHttpRequest'
            },
        }).then(function(response){
            return response.text();
        }).then(function(html){
            document.querySelector(".post").insertAdjacentHTML("beforeend",html);
            page++;
        })
    }
    var btnLoadMore = document.querySelector(".load-more");
    btnLoadMore.addEventListener("click", loadMore);
</script>
{% endblock %}

views.py


    def post_list(request, tag_slug=None):
        if tag_slug:
            tag = get_object_or_404(Tag, slug=tag_slug)
            posts = Post.objects.filter(tags__in=[tag])
        else:
            posts = Post.objects.all()
            tag = None
    
        page = request.GET.get('page')
        paginator = Paginator(posts, 1)
        try:
            posts = paginator.page(page)
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = []
    
        if request.headers.get("x-request-with") == "XMLHttRequest":
            return render(request, "social/fetch-post.html", {"posts":    posts})
    
        context = {'posts': posts, 'tag': tag}
        return render(request, "social/posts-list.html", context)
6
  • 2
    You explained your goal, but how is your current code not meeting your expectations? Commented Nov 21 at 21:28
  • @KIKOSoftware the SO guidance is almost opposite - stackoverflow.com/help/non-english-questions: "...then we do not recommend that you translate your question to English...", especially if using AI (LLM) translation - meta.stackoverflow.com/questions/424036/… Commented Nov 22 at 0:13
  • Samyar - please re-read the minimal reproducible example guidance on posting code - make sure all code shown is needed to reproduce the problem (i.e. try to remove all conditional statements by showing branch that demonstrate the problem). Also make sure to clarify what you see/expect inline in the question. When you edit the question with these details make sure to check "edit resolves issues with post" so it goes to re-open queue. Commented Nov 22 at 0:21
  • It's true, I couldn't get my point across properly. Commented Nov 22 at 19:14
  • i edit post, hope to understand Commented Nov 22 at 19:26

1 Answer 1

0

It sounds like you only want to use a portion of the returned html, not all of it. I think you'll want to use DOMParser and then parseFromSring() to parse your response into html. Then you can treat that as any other html document to insert pieces of your response into your original document.

}).then(function(html){
    const parser = new DOMParser();
    const parsedHTML = parser.parseFromString(html,"text/html");
    const targetHTML = parsedHTML.querySelector("yourSelectorHere");
    document.querySelector(".post").insertAdjacentHTML("beforeend",targetHTML);
    ...
})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.