使用Ajax从Django模型中获取模态数据



很抱歉重复这个问题,Ajax集成是一个非常广泛的主题,但我就是搞不清楚。

我有一个html表,其中有4k多行数据,每行都有一些基本信息,如姓名、地址、姓氏、电话,以及一个触发引导模式的按钮,该模式包含额外的数据,如电话2、地址2等。

我的问题是,由于我的模态位于这样的for循环中-

<tbody>
{% for opp in optika %}
<tr>
<td>{{ opp.example }}</td>
<td>{{ opp.some_field }}</td>
<td>            
<button id="testbtn" type="button" class="btn btn-success btn-sm btn-detail"
data-toggle="modal"
data-target="#detalji_modal{{ opp.pk }}"
Detalji
</button>
</td>
...
</tr>
{% include "opportunity/partials/_detalji_modal.html" %}
{% endfor %}
</tbody>

这是模态细节-


<div class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
id="detalji_modal{{ opp.pk }}"
aria-labelledby="detalji_modalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="detalji_modalLabel">Detalji</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="">
<div class="container-fluid">
<h5>{{ opp.... }}</h5>
<p>{{ opp.....title }}</p>
...
</div>
</div>
<div class="modal-footer">
<p style="margin-right: auto">Zahtev uneo/la : {{ opp.... }}</p>
...
...
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>

我也会通过视图:

@login_required(login_url='registration/login')
def OptikaList(request):
user_groups = request.user.groups.all()
optika_svi = OpportunityList.objects.all().defer(
...
).filter(opp_type__exact='optika').exclude(opp_status='zakazan', is_locked=True).order_by('eluid',
                        '-opp_status').exclude(
opp_status='odustao')
optika = [o for o in list(optika_svi)]
counter = 1000
context = {
'optika': optika[:counter],
'broj_poslova': counter,
'ukupno_poslova': optika_svi.count(),
'user_groups': user_groups,
}
#Ajax is not used for now, since idk how to implement it right.
if request.is_ajax():
data = {
'rendered_table': render_to_string('opportunity/get_more_tables.html', context=context,
request=request)}
return JsonResponse(data)
return render(request, 'opportunity/opp_optika.html', context)

这是我的ajax调用,它一团糟——

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
// Our ajax function. Specifically declared as we are
// using it in multiple places
let ajax_function = function () {
fetch_modal();
page_changing = false;
$.ajax({
url: '{% url 'opportunity:optika' %}',
type: "get",
cache: true,
data_type: 'html',
success: function (data) {
console.log("Ajaxed");
var page = dt.page(); // save page we are on
var order = dt.order(); // save ordering
var search = dt.search();
var page_length = dt.page.len();
dt.destroy(); // put table back to new
$('#dataTable').find('tbody').empty().append(data.rendered_table);
dt = $('#dataTable').DataTable(table_options); // Re-init datatable
dt.order(order); // Put back our ordering
dt.search(search);
dt.page.len(page_length);
dt.page(page).draw('page'); // Draw the page
dt.draw(false); // Put in our ordering an all the stuff
if (focused_search) {
$('input[type=search]').first().focus();
console.log('focused');
}
focus_set();
focus_lost();
page_changer();
set_detail_btn();
},
error: function (data) {
console.log("Ajax stopped!");
}
});
};
// Variables to hold our urls to the body and footer views
let body_update_link = '{% url 'opportunity:fetch_body' %}';
let footer_update_link = '{% url 'opportunity:fetch_footer' %}';
// id of opportunity currently in our modal
let modal_opp = false;
// ajax function for getting data for modal
let fetch_modal = function () {
if (modal_opp) {
$('#detalji_modal .modal-body').load(body_update_link, modal_opp.toString());
$('#detalji_modal .modal-footer').load(footer_update_link, modal_opp.toString());
}
};
// function for activating getting modal data on click on details
let set_detail_btn = function () {
$('.btn-detail').click(function () {
modal_opp = $(this).data('opp');
fetch_modal();
});
};
// Set modal_opp to false after our modal has disappeared to avoid
// unnecessary updates of an invisible modal
$('#detalji_modal').on('hidden.bs.modal', function (e) {
modal_opp = false;
});
// A central variable for putting in table options
let table_options = {
// searching: false,
// paging: false
order: [[0, "asc"]]
};
// variable holding our setInterval function so we can disable
// it if we want to
let my_timer;
// variable set to true if we are currently in the filter
let focused_search = false;
// Set our focused_search variable if our filter has focus
let focus_set = function () {
$('input[type=search]').focus(function () {
console.log('HAS FOCUS');
focused_search = true;
clearInterval(my_timer);
my_timer = false;
});
};
// Reset our focused_search variable if our filter loose focus
const focus_lost = function () {
$('input[type=search]').blur(function () {
console.log('LOST_FOCUS');
focused_search = false;
},
function () {
console.log('LOST_FOCUS');
conditional_timer_restart();
focused_search = false;
}
);
};
// Restart our timer
const conditional_timer_restart = function () {
if (!my_timer) {
my_timer = setInterval(ajax_function, 2000);
}
};
// variable set to true if we have changed paging
// needed when we click on our paging select so
// our timer restart raliably
let page_changing = false;
// Function to add some behaviour to our pager
// Will stop reloading page if we click on that select
// Will restart the reloading cycle automatically after 5
// seconds
const page_changer = function () {
$('select[name=dataTable_length]').click(function () {
console.log('Page changer init');
if (page_changing) {
page_changing = false;
} else {
clearInterval(my_timer);
my_timer = false;
setTimeout(conditional_timer_restart, 5000);
}
});
$('select[name=dataTable_length]').change(function () {
console.log('Page changer done');
page_changing = true;
my_timer = setInterval(ajax_function, 5000);
});
$('select[name=dataTable_length]').blur(function () {
console.log('Page changer lost focus');
if (!my_timer) {
my_timer = setInterval(ajax_function, 5000);
}
});
};
set_detail_btn = function () {
$('.btn-detail').click(function () {
modal_opp = $(this).data('opp');
fetch_modal();
});
$('.btn-detail').hover(
function () {
console.log('hovered');
clearInterval(my_timer);
my_timer = false;
},
function () {
console.log('hoveroff ');
conditional_timer_restart();
}
);
};
// Our intial init of the table
let dt = $('#dataTable').DataTable(table_options);
focus_set();
focus_lost();
page_changer();
set_detail_btn();
// my_timer = setInterval(ajax_function, 1000);
});
</script>

views.py中的fetch_body和fetch_footer函数-

def fetch_body(request):
id = list(request.GET.keys())[0]
opp = OpportunityList.objects.get(pk=id)
return HttpResponse(
render_to_string('opportunity/partials/_modal_body.html', context={'opp': opp}, request=request))

def fetch_footer(request):
id = list(request.GET.keys())[0]
opp = OpportunityList.objects.get(pk=id)
return HttpResponse(
render_to_string('opportunity/partials/_modal_footer.html', context={'opp': opp}, request=request))

页面本身需要5秒以上的时间才能加载,而且它有超过20mb的数据,这是一个巨大的过度消耗。

基本上,我需要在模态打开/打开按钮(testbtn(点击时获取模态主体(数据(。

或者可能只加载用于显示带有分页的对象的详细信息(模态(。

由于我对Ajax(这对我来说仍然是一件令人困惑的事情(和jQuery不太好,请有人向我解释一下这方面的最佳方法(示例会很棒!(。

谢谢!

事实证明,Ajax并不那么难理解。

所以基本上没有正确的答案,你应该选择最适合你的选项。

如本链接之前所述,我如何将Ajax与Django应用程序集成?对初学者有很好的详细解释。

最新更新