Django generic.ListVIew: отображение деталей элемента списка на той же странице (~ объединение ListView и DetailView)

Я хочу отобразить подробную информацию о щелкнутом элементе ListView на той же странице, которая содержит ListView (грубо говоря, объединить generic.ListView с generic.DetailView). Я сделал следующее:

generic.ListView of Contacts:

from .models import Contact
from django.views import generic

class ContactList(generic.ListView):
    model = Contact
    context_object_name = 'contacts'
    template_name = 'contacts/list.html'

Шаблон contacts/list.html включает запрос JS Fetch (GET) для получения щелкнутого элемента:

{% block content %}
{% if contacts %}
    <ul>
    {% for contact in contacts %}
        <li><a id="{{ contact.id }}" onClick="showDetails(this.id)">{{ contact.first_name }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    No contacts. 
{% endif %}

<div id='contactDetail'></div>

<script type="text/javascript">
  function showDetails(contactId){
    console.log(contactId);
    fetch(`http://127.0.0.1:8080/contacts/${contactId}`, {
        headers: {
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
        },
    })
    .then(response => {
        // should 500 be processed?
        return response.json();
    })
    .then(data => {
        //Perform actions with the response data from the view
        window.onload = function() {
            // build html markup next
            document.getElementById("contactDetail").innerHTML= ...;
        } 
    })
  }
</script>
{% endblock content %}

Представление Django, которое обрабатывает этот запрос Fetch-GET, следующее:

from django.shortcuts import get_object_or_404
from django.forms.models import model_to_dict

def contact_details(request, contact_id):
    contact = get_object_or_404(Contact, pk=contact_id)
    contact = {k: v for k, v in model_to_dict(contact).items() if v}
    return JsonResponse(contact)

Правильно ли это?

В вашем способе нет почти ничего плохого.

Хотя производство, вы должны использовать пагинацию . Таким образом, данных не должно быть слишком много, и я думаю, что было бы лучше возвращать все поля вместе со списком, но сначала скрывать дополнительные поля и просто разворачивать их по клику.

Вернуться на верх