我们遇到了一个奇怪的问题。有一个Transaction
模型,它的管理员具有一个自定义列revert
,该列将POST发送到服务器。
奇怪的是,第一行中的revert
不起作用。我只是不渲染<form>
标签。其他行正常工作。
@admin.register(Transaction)
class TransactionAdmin(admin.ModelAdmin):
list_display = ['code', 'created', 'modified', 'wallet', 'title', 'amount', 'invoice_link','revert']
def get_queryset(self, request):
qs = super().get_queryset(request)
self.request = request
return qs
def revert(self, obj: Transaction):
if obj.pk:
html = render_to_string("alex_wallets/transactions/revert_block.html", context={'transaction': obj},
request=self.request)
return mark_safe(format_html(html))
revert_block.html
<div>
<form onsubmit="return confirm('Naozaj chcete vytvoriť opačnú transakciu?')"
action="{% url "wallets:revert_transaction" transaction.pk %}" method="post">
{% csrf_token %}
<button style=" color: #fff; background-color: #00D996; border: 0; border-radius:4px; cursor: pointer; padding: 5px 10px;" type="submit">Vrátiť
</button>
</form>
</div>
这是第一行的html
(列还原):
<td class="field-revert"><div>
<input type="hidden" name="csrfmiddlewaretoken" value="agpE7aEExG19YJ3n8wDv88sC7J7u7aHXa5Od3vVJptA6t0on1gGENECaTt2Qp7hb">
<button style=" color: #fff; background-color: #00D996; border: 0; border-radius:4px; cursor: pointer; padding: 5px 10px;" type="submit">Vrátiť
</button>
</div></td>
这是除第一行还原列之外的html
:
<td class="field-revert"><div>
<form onsubmit="return confirm('Naozaj chcete vytvoriť opačnú transakciu?')" action="/alex/transakcie/transactions/revert/45/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="Pc7Pt41tXgMUyZyKOORUb2gQutkqCkjpP1woppiyP3lR3gTKHyU3QyqogdfMUhTD">
<button style=" color: #fff; background-color: #00D996; border: 0; border-radius:4px; cursor: pointer; padding: 5px 10px;" type="submit">Vrátiť
</button>
</form>
</div></td>
inline
表格也是如此。
您知道问题出在哪里吗?
编辑:
它始终是第一行。我可以对行进行重新排序,并且始终是第一个显示不正确的行。而且我已经在django-jet
中进行了检查,并且还内置了原始django-admin
。两者都有这个问题。
EDIT2:
在调试器中,我看到html
始终正确呈现,即使对于第一行也是如此。
EDIT3:
它与浏览器无关。 Chrome
和Firefox
EDIT4:
所以我离根更近了。我注意到它已正确呈现,但浏览器删除了第一个表单。可能是因为changelist
表在默认情况下被另一种形式包围,但不知道该怎么办。
答案 0 :(得分:0)
因此,问题在于整个form
表周围有一个很大的默认changelist
,浏览器不喜欢嵌套表单。因此,我们需要采用其他方式。
因此,我创建了一个js
代码,该代码在需要时动态创建一个新表单。
还原模板
<div>
<button class="postbtn" data-csrf="{{ csrf_token }}"
data-action="{% url "wallets:revert_transaction" transaction.pk %}"
style=" color: #fff; background-color: #00D996; border: 0; border-radius:4px; cursor: pointer; padding: 5px 10px;"
type="button">Vrátiť
</button>
</div>
然后我创建了一个buttonpost.js
function nonAjaxPost(action, input) {
'use strict';
var form;
form = jQuery('<form />', {
action: action,
method: 'post',
style: 'display: none;'
});
if (typeof input !== 'undefined' && input !== null) {
jQuery.each(input, function (name, value) {
jQuery('<input />', {
type: 'hidden',
name: name,
value: value
}).appendTo(form);
});
}
form.appendTo('body').submit();
}
jQuery(document).ready(function () {
jQuery('button[class="postbtn"]').click(function () {
if (confirm("Potvrďte vrátenie transakcie")) {
var ths = jQuery(this);
var url = ths.attr('data-action');
var csrf = ths.attr('data-csrf');
nonAjaxPost(url, {'csrfmiddlewaretoken': csrf});
}
})
});
可以使用class Media
包括哪些内容:
class ....Admin(..):
class Media:
js = ['...buttonpost.js']
将其包含在AdminInline