Django在admin中的get_queryset()是否可以防止恶意对象保存?

时间:2018-11-12 19:35:37

标签: python django django-forms django-admin

我正在Django中开发一个多租户应用程序。在Django管理员中,使用get_queryset()根据用户过滤了一些查询集。

到目前为止,当用户从Django更改表单中更新对象时,我将通过使用工厂函数创建ModelAdmin表单来捕获HttpRequest对象来创建Guest表单来验证数据,然后确保user对象的class Guest(models.Model): guest_name = models.CharField(max_length=64) user = models.ForeignKey(User, on_delete=models.CASCADE) 是当前用户:

示例

models.py

@admin.register(Guest)
class GuestAdmin(admin.ModelAdmin):
    def get_queryset(self, request)
        qs = super().get_queryset(request)
        return qs.filter(user=request.user)

    def get_form(self, request, obj=None, **kwargs):
        self.form = _guest_admin_form_factory(request)
        return super().get_form(request, obj, **kwargs)

admin.py

def _guest_admin_form_factory(request):
    class GuestAdminForm(forms.ModelForm):
        class Meta:
            model = Guest
            exclude = []

         def clean_user(self):
             user = self.cleaned_data.get('user', None)
             if not user:
                 return user
             if user != request.user:
                 raise forms.ValidationError('Invalid request.')
             return user
    return GuestAdminForm

forms.py

get_queryset()

我想到Django可能会使用ModelAdmin方法为我验证此方法,因为一些简单的日志记录表明,当从变更表单中更新对象时,该方法被调用了两次。

是这种情况,还是我需要坚持通过 $(function(){ ticker(); }); function ticker() { var varLISTID = "<?php echo $listID; ?>"; var varUSERACCOUNTNAME = "<?php echo $useraccountname; ?>"; var varITEMACCOUNTNAME = "<?php echo $itemaccountname; ?>"; var varSELECTEDUSER=document.getElementById('datacatchuser').getAttribute("data-variable-SELECTEDUSER"); var mybutton= "messageboxreplybutton.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER; $('#buttonbox').load(mybutton); var mylink = "loadmessages.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER; $('#infobox1').load(mylink); var myotherlink = "contactselect.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER; $('#containercontact').load(myotherlink); console.log("timer fired 2sec") } var myTimer = setInterval(ticker, 10000); function editBuyermessage(messageid){ var varmessageid=messageid;//the div holding the data var var varmessageID = document.getElementById('Buyer'+varmessageid+'').getAttribute("data-variable-messageID");//the id in the database var varMESSAGEDATE = document.getElementById('Buyer'+varmessageid+'').getAttribute("data-variable-MESSAGEDATE");//message's senders username var varLISTID = "<?php echo $listID; ?>"; var varUSERACCOUNTNAME = "<?php echo $useraccountname; ?>"; var varITEMACCOUNTNAME = "<?php echo $itemaccountname; ?>"; var varMESSAGEACCOUNTNAME = document.getElementById('Buyer'+varmessageid+'').getAttribute("data-variable-MESSAGEACCOUNTNAME");//message's senders username var varSELECTEDUSER = document.getElementById('datacatchuser').getAttribute("data-variable-SELECTEDUSER"); if (varUSERACCOUNTNAME==varMESSAGEACCOUNTNAME){ var ebm=document.getElementById('editBuyer'+varmessageid+''); if ( $(ebm).attr("contentEditable") == "false" ){ $('#editBuyer'+varmessageid+'').prop('contenteditable', true); $('#editBuyer'+varmessageid+'').css('outline', '0px'); $('#editBuyer'+varmessageid+'').css('border', '1px dashed #07f310'); $('#boxBEDIT'+varmessageid+'').text('Save'); console.log("Paused for Typing") clearInterval(myTimer); } else { $('#editBuyer'+varmessageid+'').prop('contenteditable', false); $('#editBuyer'+varmessageid+'').css('outline', '0px'); $('#editBuyer'+varmessageid+'').css('border', '1px solid transparent'); $('#boxBEDIT'+varmessageid+'').text('Edit'); clearInterval(myTimer); myTimer = setInterval(ticker, 10000); console.log("Restart Timer") var gotmessage = $('#editBuyer'+varmessageid+'').text(); var regex= /fuck|cunt|slag|bitch|fukker|nonce|prick|bollocks|dick|shag|slut|bastard|fuk|spunk|shit|wank/gi; gotmessage=gotmessage.replace(regex, "****"); var Buyer="Buyer"; if (gotmessage !="") { $.ajax({ url:"insertedit.php", type: "POST", dataType: 'text', cache: false, data:{ BuyerSeller:Buyer, messageID:varmessageID, messagesent:gotmessage, listID:varLISTID, messageDate:varMESSAGEDATE, useraccountname:varUSERACCOUNTNAME, }, async: true, success:function(data){ var mylink = "loadmessages.php?listID=" + varLISTID + "&useraccountname="+ varUSERACCOUNTNAME + "&itemaccountname="+ varITEMACCOUNTNAME + "&selecteduser="+ varSELECTEDUSER; $('#infobox1').load(mylink); var myotherlink = "contactselect.php?listID=" + varLISTID + "&useraccountname=" + varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER; $('#containercontact').load(myotherlink); } }); }// if gotmessage not empty else { alert('Empty Message - Not Sent'); return false; } } } else { alert("Sorry You Cannot Edit "+varMESSAGEACCOUNTNAME+"'s Message!"); } } function editSellermessage(messageid){ var varmessageid=messageid;//the div holding the data var var varmessageID = document.getElementById('Seller'+varmessageid+'').getAttribute("data-variable-messageID");//the id in the database var varMESSAGEDATE = document.getElementById('Seller'+varmessageid+'').getAttribute("data-variable-MESSAGEDATE");//message's senders username var varMESSAGEACCOUNTNAME = document.getElementById('Seller'+varmessageid+'').getAttribute("data-variable-MESSAGEACCOUNTNAME");//message's senders username var varSELECTEDUSER=document.getElementById('datacatchuser').getAttribute("data-variable-SELECTEDUSER"); var varLISTID = "<?php echo $listID; ?>"; var varUSERACCOUNTNAME = "<?php echo $useraccountname; ?>"; var varITEMACCOUNTNAME = "<?php echo $itemaccountname; ?>"; if (varUSERACCOUNTNAME==varMESSAGEACCOUNTNAME){ var ebm=document.getElementById('editSeller'+varmessageid+''); if ( $(ebm).attr("contentEditable") == "false" ){ $('#editSeller'+varmessageid+'').prop('contenteditable', true); $('#editSeller'+varmessageid+'').css('outline', '0px'); $('#editSeller'+varmessageid+'').css('border', '1px dashed #07f310'); $('#boxSEDIT'+varmessageid+'').text('Save'); console.log("Paused for Typing") clearInterval(myTimer); } else { //else save $('#editSeller'+varmessageid+'').prop('contenteditable', false); $('#editSeller'+varmessageid+'').css('outline', '0px'); $('#editSeller'+varmessageid+'').css('border', '1px solid transparent'); $('#boxSEDIT'+varmessageid+'').text('Edit'); clearInterval(myTimer); myTimer = setInterval(ticker, 10000); console.log("Restart Timer") var gotmessage = $('#editSeller'+varmessageid+'').text(); var regex= /fuck|cunt|slag|bitch|fukker|nonce|prick|bollocks|dick|shag|slut|bastard|fuk|spunk|shit|wank/gi; gotmessage=gotmessage.replace(regex, "****"); var Seller="Seller"; if (gotmessage !="") { $.ajax({ url:"insertedit.php", type: "POST", dataType: 'text', cache: false, data:{ BuyerSeller:Seller, messageID:varmessageID, messagesent:gotmessage, listID:varLISTID, messageDate:varMESSAGEDATE, useraccountname:varUSERACCOUNTNAME, sendto:varSELECTEDUSER, }, async: true, success:function(data){ var mylink = "loadmessages.php?listID=" + varLISTID + "&useraccountname="+ varUSERACCOUNTNAME + "&itemaccountname=" + varITEMACCOUNTNAME + "&selecteduser=" + varSELECTEDUSER; $('#infobox1').load(mylink); } }); }// if gotmessage not empty else { alert('Empty Message - Not Sent'); return false; } } } else { alert("Sorry You Cannot Edit "+varMESSAGEACCOUNTNAME+"'s Message!"); } } 表单进行验证?

1 个答案:

答案 0 :(得分:1)

documented的实现方法是定义has_change_permission()

@admin.register(Guest)
class GuestAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        return super().get_queryset(request).filter(user=request.user)

    def has_change_permission(self, request, obj=None):
        return (obj is None or obj.user == request.user)

不需要弄糊涂。