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)
Правильно ли это?
В вашем способе нет почти ничего плохого.
Хотя производство, вы должны использовать пагинацию . Таким образом, данных не должно быть слишком много, и я думаю, что было бы лучше возвращать все поля вместе со списком, но сначала скрывать дополнительные поля и просто разворачивать их по клику.