Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django';s GenericsTackedLine管理员_Python_Django_Python 3.x_Django Forms_Django Admin - Fatal编程技术网

Python 如何在Django';s GenericsTackedLine管理员

Python 如何在Django';s GenericsTackedLine管理员,python,django,python-3.x,django-forms,django-admin,Python,Django,Python 3.x,Django Forms,Django Admin,使用Django 1.9(Python 3.4)中的GenericsTackedLine,我想在Django管理中保存我的模型之前访问请求对象 使用MediaItemAdmin时,我可以在运行obj.save()之前拦截save函数,如下例所示: admin.py class StuffAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): # Do some stuff her

使用Django 1.9(Python 3.4)中的GenericsTackedLine,我想在Django管理中保存我的模型之前访问请求对象

使用
MediaItemAdmin
时,我可以在运行
obj.save()
之前拦截save函数,如下例所示:

admin.py

class StuffAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # Do some stuff here like obj.user = request.user before saving.
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel

    def save_model(self, request, obj, form, change):
        print("I'm never run :(")
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel
    form = StuffForm

class StuffForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StuffForm, self).__init__(*args, **kwargs)

    def save_model(self, request, obj, form, change):
        print("Still not run!(")
        obj.save()

    def save_form(self, request, obj, form, change):
        print("Work already!")
        obj.save()
但是,使用
GenericStackedInline
无法获得相同的行为或“hook”。它似乎直接调用模型保存方法:

admin.py

class StuffAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # Do some stuff here like obj.user = request.user before saving.
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel

    def save_model(self, request, obj, form, change):
        print("I'm never run :(")
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel
    form = StuffForm

class StuffForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StuffForm, self).__init__(*args, **kwargs)

    def save_model(self, request, obj, form, change):
        print("Still not run!(")
        obj.save()

    def save_form(self, request, obj, form, change):
        print("Work already!")
        obj.save()
据我所知,
GenericStackedInline
继承自
表单
,因此我也尝试使用表单并覆盖该表单,如本例所示:

admin.py

class StuffAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # Do some stuff here like obj.user = request.user before saving.
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel

    def save_model(self, request, obj, form, change):
        print("I'm never run :(")
        obj.save()
class StuffAdmin(GenericStackedInline):
    model = StuffModel
    form = StuffForm

class StuffForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StuffForm, self).__init__(*args, **kwargs)

    def save_model(self, request, obj, form, change):
        print("Still not run!(")
        obj.save()

    def save_form(self, request, obj, form, change):
        print("Work already!")
        obj.save()
我已经搜索了stackoverflow,但大多数都没有得到响应,如这里所示,或者说使用
init
执行类似
self.request=kwargs.pop('request')
的操作,但是,
request
从未在这里传递,对吗

无论如何,在调用model save()之前,知道如何调用request对象并更新实例吗?

保存“内联线”的方法是
ModelAdmin
的一部分,而不是
InlineModelAdmin

class BarInline(GenericStackedInline):
    model = Bar

class FooModelAdmin(ModelAdmin):
    model = Foo
    inlines = [BarInline]

    def save_formset(self, request, form, formset, change):
        """
        `form` is the base Foo form
        `formset` is the ("Bar") formset to save
        `change` is True if you are editing an existing Foo,
                    False if you are creating a new Foo
        """
        if formset_matches_your_inline_or_some_requirement(formset):
            do_something_with(request)
        super().save_formset(request, form, formset, change)
如果要检查表单集是否为
BarInline
的表单集,可以执行以下操作:

class BarInline(GenericStackedInline):
    model = Bar

    def get_formset(self, *args, **kwargs):
        formset = super().get_formset(*args, **kwargs)
        formset.i_come_from_bar_inline = True
        return formset


class FooModelAdmin(ModelAdmin):
    model = Foo
    inlines = [BarInline]

    def save_formset(self, request, form, formset, change):
        if getattr(formset, 'i_come_from_bar_inline', False):
            do_something_with(request)
        super().save_formset(request, form, formset, change)
class BarForm(ModelForm):
    model = Bar

    def save(self, commit=True):
        do_something_with(self.request, self.instance)
        return super().save(commit)  # Get object but don't save it
或者更好的是,让它成为通用的:

class BarInline(GenericStackedInline):
    model = Bar

    def pre_save_formset(self, request, form, model_admin, change):
       """Do something here with `request`."""

class FooModelAdmin(ModelAdmin):
    model = Foo
    inlines = [BarInline]

    def save_formset(self, request, form, formset, change):
        if hasattr(formset, 'pre_save_formset'):
            formset.pre_save_formset(request, form, self, change)
        super().save_formset(request, form, formset, change)
        if hasattr(formset, 'post_save_formset'):
            formset.post_save_formset(request, form, self, change)

如果您需要在每次表单保存之前而不是在每次表单集之前处理请求,则必须使用您自己的表单和表单集通过表单集将请求传播到表单:

from django.forms import ModelForm
from django.forms.models import BaseInlineFormSet

class BarForm(ModelForm):
    model = Bar

    def __init__(self, *args, **kwargs):
        request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)
        self.request = request

    def save(self, commit=True):
        print(self.request)
        print(self.instance)
        obj = super().save(False)  # Get object but don't save it
        do_something_with(self.request, obj)
        if commit:
            obj.save()
            self.save_m2m()
        return obj

class BarFormSet(BaseInlineFormSet):

    @property
    def request(self):
        return self._request

    @request.setter
    def request(self, request):
        self._request = request
        for form in self.forms:
            form.request = request

class BarInline(GenericStackedInline):
    codel = Bar
    form = BarForm
    formset = BarFormSet


class FooModelAdmin(ModelAdmin):
    inlines = [BarInline]

    def _create_formsets(self, request, obj, change):
        formsets, inline_instances = super()._create_formsets(request, obj, change)
        for formset in formsets:
            formset.request = request
        return formsets, inline_instances
根据您的用例,save方法也可能看起来像这样:

class BarInline(GenericStackedInline):
    model = Bar

    def get_formset(self, *args, **kwargs):
        formset = super().get_formset(*args, **kwargs)
        formset.i_come_from_bar_inline = True
        return formset


class FooModelAdmin(ModelAdmin):
    model = Foo
    inlines = [BarInline]

    def save_formset(self, request, form, formset, change):
        if getattr(formset, 'i_come_from_bar_inline', False):
            do_something_with(request)
        super().save_formset(request, form, formset, change)
class BarForm(ModelForm):
    model = Bar

    def save(self, commit=True):
        do_something_with(self.request, self.instance)
        return super().save(commit)  # Get object but don't save it

管理类不从表单继承;它们包括表格。ModelForms没有
save\u model
save\u form
方法,它们只有
save
方法。完全可以重写该方法,但它不接受
请求
;您还需要重写
\uuuu init\uuuu
以接受该参数,并从modeladmin的
get\u form\u kwargs
方法传递它。

好的,这是有意义的。您知道请求参数在
\uuuu init\uuuu
中隐藏的位置吗?它在post.DATA等或self中?它不隐藏在任何地方。您必须在方法签名中显式接受它,或者从
**kwargs
获取它,并将其存储在实例属性中。谢谢,我可以看到我现在使用了def save(),但这并没有获取请求对象。我获取错误
set_request()在这一行
formset.set\u request(request)
上缺少1个必需的位置参数:“self”
,这是因为在这个阶段没有“self”?这是因为
get\u formset()
返回一个formset类,而不是一个实例。我的错误。我确定了我的答案。