You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django项目中如何为JavaScript动态加载的博客内容应用原有HTML卡片样式?

How to apply existing HTML card styling to dynamically loaded content via JavaScript?

I implemented a "Load More" button on my blog page using JavaScript to dynamically load blog content, but I can't figure out how to make the dynamically loaded content use the original HTML card styling.

My original HTML template (Django):

{% for filt in object_list %} 
<div class="card mb-4"> 
{% if not filt.blog_cover_image %} 
<img class="img-fluid rounded" style="max-height:1000px;max-width:1200px;" src="https://via.placeholder.com/900x300" alt="..." /> 
{% else %} 
<img class="img-fluid rounded" style="max-height:1000px;max-width:1200px;" src="{{ filt.blog_cover_image.url }}" alt="..." /> 
{%endif%} 
<div class="card-body"> 
<h2 class="card-title"><a href="{% url 'blog:blog-detail' filt.slug %}">{{filt.title}}</a></h2> 
<p class="card-text">{{filt.body|striptags|safe|slice:":250" }}</p> 
<a class="btn btn-primary" href="{% url 'blog:blog-detail' filt.slug %}">Read More →</a> 
</div> 
<div class="card-footer text-muted"> 
Posted on ({{filt.created_at}}) 
<div class="author">{{filt.author.first_name}}&nbsp{{filt.author.last_name}}&nbsp;{% if user.is_authenticated %}{% if user.id == blog.author.id or user.is_superuser %}<a href="{% url 'blog:blog-update' filt.slug %}"><b>(Edit Blog)</b></a>&nbsp;<a href="{% url 'blog:blog-delete' filt.slug %}"><b>(Delete Blog)</b></a>{% endif %}{% endif %}</div> 
</div> 
</div> 
{% endfor %} 

HTML structure for "Load More" functionality:

<div id="posts-box"></div> 
<div id="spinner-box" class="not-visible"> 
<div class="spinner-border text-primary" role="status"></div> 
</div> 
<div id="loading-box"> 
<button class="btn btn-primary" id="load-btn">Load more</button> 
</div> 

My JavaScript code:

const postsBox = document.getElementById('posts-box') 
console.log(postsBox) 
const spinnerBox = document.getElementById('spinner-box') 
const loadBtn = document.getElementById('load-btn') 
const loadBox = document.getElementById('loading-box') 
let visible = 3 
const handleGetData = () => { 
$.ajax({ 
type: 'GET', 
url: `/posts-json/${visible}/`, 
success: function(response){ 
maxSize = response.max 
const data = response.data 
spinnerBox.classList.remove('not-visible') 
setTimeout(()=>{ 
spinnerBox.classList.add('not-visible') 
data.map(post=>{ 
console.log(post.id) 
postsBox.innerHTML += `<div class="card mb-4"> ${post.title} <br> ${post.body} </div>` 
}) 
if(maxSize){ 
console.log('done') 
loadBox.innerHTML = "<h4>No more posts to load</h4>" 
} 
}, 500) 
}, 
error: function(error){ 
console.log(error) 
} 
}) 
} 
handleGetData() 
loadBtn.addEventListener('click', ()=>{ 
visible += 3 
handleGetData() 
})

How can I apply the original HTML styling to the content I generate dynamically with JavaScript?


Answer

Hey there! The issue right now is that your JavaScript is only adding a barebones card container with just the title and body—you need to replicate the full card structure from your original Django template in your JS template string. Here's how to do it step by step:

1. First, make sure your backend JSON response includes all required fields

Before updating the JS, confirm your /posts-json/${visible}/ endpoint returns every piece of data you need for the card:

  • slug (for the detail/edit/delete URLs)
  • blog_cover_image_url (or null if there's no image)
  • title
  • truncated_body (pre-processed to remove tags and slice to 250 characters—better to do this on the backend than frontend)
  • created_at (raw ISO date or pre-formatted string)
  • author_first_name, author_last_name
  • is_editable (a boolean indicating if the current user can edit/delete the post—avoids complex auth logic in JS)
  • edit_url and delete_url (or you can construct these frontend-side if you have the slug)

2. Replace your JS card template with the full structure

Update the data.map(post => { ... }) block in your handleGetData function to use the complete card HTML, replacing Django template variables with your post object properties:

data.map(post => {
    // Build cover image with conditional placeholder logic
    const coverImage = post.blog_cover_image_url 
        ? `<img class="img-fluid rounded" style="max-height:1000px;max-width:1200px;" src="${post.blog_cover_image_url}" alt="Blog cover" />`
        : `<img class="img-fluid rounded" style="max-height:1000px;max-width:1200px;" src="https://via.placeholder.com/900x300" alt="Blog cover placeholder" />`;

    // Build edit/delete buttons only if user has permission
    const editDeleteButtons = post.is_editable 
        ? `<a href="${post.edit_url}"><b>(Edit Blog)</b></a>&nbsp;<a href="${post.delete_url}"><b>(Delete Blog)</b></a>`
        : '';

    // Format date to match your original template's style
    const formattedDate = new Date(post.created_at).toLocaleDateString('en-US', {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
    });

    // Assemble the full card HTML
    const cardHtml = `
        <div class="card mb-4">
            ${coverImage}
            <div class="card-body">
                <h2 class="card-title"><a href="/blog/${post.slug}/">${post.title}</a></h2>
                <p class="card-text">${post.truncated_body}</p>
                <a class="btn btn-primary" href="/blog/${post.slug}/">Read More →</a>
            </div>
            <div class="card-footer text-muted">
                Posted on (${formattedDate})
                <div class="author">${post.author_first_name}&nbsp;${post.author_last_name}&nbsp;${editDeleteButtons}</div>
            </div>
        </div>
    `;

    postsBox.innerHTML += cardHtml;
})

3. Key notes to keep in mind

  • URL Construction: If you don't want to return edit_url/delete_url from the backend, you can build them using the slug (e.g., /blog/edit/${post.slug}/)—just ensure they match your Django URL patterns.
  • Performance: For large numbers of posts, innerHTML += can get slow. Instead, build an array of card strings and do postsBox.innerHTML += cards.join('') once at the end.
  • Security: Always validate edit/delete permissions on the backend, even if you hide the buttons frontend-side—never trust frontend-only auth checks.
  • Date Formatting: Adjust the toLocaleDateString options to match the date style in your original template.

This will make your dynamically loaded posts look identical to the ones rendered by your Django template!


内容的提问来源于stack exchange,提问作者boyenec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:17:35