开发者

Passing session data to ModelForm inside of ModelAdmin

I'm trying to initialize the form attribute for MyModelAdmin class inside an instance method, as follows:

class MyModelAdmin(admin.ModelAdmin): 
    def queryset(self, request):
        MyModelAdmin.form = MyModelForm(request.user)

My goal is to customize the editing form of MyModelForm based on the current session. When I try this howeve开发者_StackOverflow社区r, I keep getting an error (shown below). Is this the proper place to pass session data to ModelForm? If so, then what may be causing this error?

TypeError at ...

Exception Type: TypeError

Exception Value: issubclass() arg 1 must be a class

Exception Location: /usr/lib/pymodules/python2.6/django/forms/models.py in new, line 185


Combining the good ideas in Izz ad-Din Ruhulessin's answer and the suggestion by Cikić Nenad, I ended up with a very awesome AND concise solution below:

class CustomModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.form.request = request #so we can filter based on logged in user for example
        return super(CustomModelAdmin, self).get_form(request,**kwargs)

Then just set a custom form for the modeladmin like:

form = CustomAdminForm

And in the custom modelform class access request like:

self.request #do something with the request affiliated with the form


Theoretically, you can override the ModelAdmin's get_form method:

# In django.contrib.admin.options.py
def get_form(self, request, obj=None, **kwargs):
    """
    Returns a Form class for use in the admin add view. This is used by
    add_view and change_view.
    """
    if self.declared_fieldsets:
        fields = flatten_fieldsets(self.declared_fieldsets)
    else:
        fields = None
    if self.exclude is None:
        exclude = []
    else:
        exclude = list(self.exclude)
    exclude.extend(kwargs.get("exclude", []))
    exclude.extend(self.get_readonly_fields(request, obj))
    # if exclude is an empty list we pass None to be consistant with the
    # default on modelform_factory
    exclude = exclude or None
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": curry(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    return modelform_factory(self.model, **defaults)

Note that this returns a form class and not a form instance.


If some newbie, as myself, passes here:
I had to define:

class XForm(forms.ModelForm):    
    request=None    

then at the end of the previous post

    mfc=modelform_factory(self.model, **defaults)   
    self.form.request=request   #THE IMPORTANT statement   
    return mfc


i use queryset fot filtering records, maybe this example help you:

.....
.....
def queryset(self, request):
    cuser = User.objects.get(username=request.user)

    qs = self.model._default_manager.get_query_set()
    ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)

    if ordering:
        qs = qs.order_by(*ordering)

    qs = qs.filter(creator=cuser.id)

    return qs


Here is a production/thread-safe variation from nemesisfixx solution:

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


class CustomModelAdmin(admin.ModelAdmin):

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

Now in ModelForm, we can access it by

self.request

Example:

class CustomModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(TollConfigInlineForm, self).__init__(*args, **kwargs)
        request = self.request
        user = request.user
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜