Code

Opened 6 years ago

Closed 6 years ago

Last modified 5 years ago

#10005 closed (invalid)

Incorrect classname assumed in ModelFormMetaClass modelform_factory()

Reported by: Jon Owned by: nobody
Component: Forms Version:
Severity: Keywords: modelform_factory assumption
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

debug dump:
  c:\python26\lib\site-packages\django\core\management\commands\runserver.py(61)inner_run
-> run(addr, int(port), handler)
  c:\python26\lib\site-packages\django\core\servers\basehttp.py(676)run()
-> httpd.serve_forever()
  c:\python26\lib\socketserver.py(226)serve_forever()
-> self._handle_request_noblock()
  c:\python26\lib\socketserver.py(281)_handle_request_noblock()
-> self.process_request(request, client_address)
  c:\python26\lib\socketserver.py(307)process_request()
-> self.finish_request(request, client_address)
  c:\python26\lib\socketserver.py(320)finish_request()
-> self.RequestHandlerClass(request, client_address, self)
  c:\python26\lib\site-packages\django\core\servers\basehttp.py(558)__init__()
-> BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
  c:\python26\lib\socketserver.py(615)__init__()
-> self.handle()
  c:\python26\lib\site-packages\django\core\servers\basehttp.py(603)handle()
-> handler.run(self.server.get_app())
  c:\python26\lib\site-packages\django\core\servers\basehttp.py(278)run()
-> self.result = application(self.environ, self.start_response)
  c:\python26\lib\site-packages\django\core\servers\basehttp.py(635)__call__()
-> return self.application(environ, start_response)
  c:\python26\lib\site-packages\django\core\handlers\wsgi.py(239)__call__()
-> response = self.get_response(request)
  c:\python26\lib\site-packages\django\core\handlers\base.py(86)get_response()
-> response = callback(request, *callback_args, **callback_kwargs)
  c:\python26\lib\site-packages\django\contrib\admin\sites.py(157)root()
-> return self.model_page(request, *url.split('/', 2))
  c:\python26\lib\site-packages\django\views\decorators\cache.py(44)_wrapped_view_func()
-> response = view_func(request, *args, **kwargs)
  c:\python26\lib\site-packages\django\contrib\admin\sites.py(176)model_page()
-> return admin_obj(request, rest_of_url)
  c:\python26\lib\site-packages\django\contrib\admin\options.py(198)__call__()
-> return self.change_view(request, unquote(url))
  c:\python26\lib\site-packages\django\db\transaction.py(238)_commit_on_success()
-> res = func(*args, **kw)
  c:\python26\lib\site-packages\django\contrib\admin\options.py(566)change_view()
-> ModelForm = self.get_form(request, obj)
  c:\python26\lib\site-packages\django\contrib\admin\options.py(278)get_form()
-> return modelform_factory(self.model, **defaults)
> c:\python26\lib\site-packages\django\forms\models.py(334)modelform_factory()
-> return ModelFormMetaclass(class_name, (form,), {'Meta': Meta,
(Pdb) l 328
323
324     def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
325                            formfield_callback=lambda f: f.formfield()):
326         # HACK: we should be able to construct a ModelForm without creating
327         # and passing in a temporary inner class
328         class Meta:
329             pass
330         setattr(Meta, 'model', model)
331         setattr(Meta, 'fields', fields)
332         setattr(Meta, 'exclude', exclude)
333         class_name = model.__name__ + 'Form'
(Pdb) l
334  ->     return ModelFormMetaclass(class_name, (form,), {'Meta': Meta,
335                                   'formfield_callback': formfield_callback})
336
337
338     # ModelFormSets ##############################################################
339
340     class BaseModelFormSet(BaseFormSet):
341         """
342         A ``FormSet`` for editing a queryset and/or adding new objects to it.
343         """
344         model = None
(Pdb) p model
<class 'flint.photography.models.Import'>
(Pdb) p form
<class 'flint.photography.admin.ImportAdminForm'>
(Pdb) p class_name
'ImportForm'
[************* INCORRECT ***************]

yields exception:

165         def value_from_datadict(self, data, files, name):
166             """
(Pdb)
167             Given a dictionary of data and this widget's name, returns the value
168             of this widget. Returns None if it's not provided.
169             """
170             import pdb; pdb.set_trace()
171  ->         return data.get(name, None)
172
173         def _has_changed(self, initial, data):
174             """
175             Return True if data differs from initial.
176             """
177             # For purposes of seeing whether something has changed, None is
(Pdb) n
AttributeError: "'ImportForm' object has no attribute 'get'"
> c:\python26\lib\site-packages\django\forms\widgets.py(171)value_from_datadict()
-> return data.get(name, None)
(Pdb)

Abridged sample code:

class ImportAdminAddForm(forms.ModelForm):

    class Meta:
        model = Import

class ImportAdminForm(forms.ModelForm):
        
    class Meta:
        model = Import

class ImportAdminAdd(admin.ModelAdmin):
    form = ImportAdminAddForm

class ImportAdmin(admin.ModelAdmin):
    form = ImportAdminForm

Attachments (0)

Change History (7)

comment:1 Changed 6 years ago by Jon

Please hide/remove submitters email address - would appreciate update but not bot spam. Thanks.

comment:2 Changed 6 years ago by Jon

Amendment - code to reproduce exception:

class ImportAdminAddForm(forms.ModelForm):

    class Meta:
        model = Import

class ImportAdminForm(forms.ModelForm):

    class Meta:
        model = Import

    def __init__(self, *args, **kwargs):
        super(ImportAdminForm, self).__init__(self, *args, **kwargs)    ### Causes Exception

class ImportAdminAdd(admin.ModelAdmin):

    form = ImportAdminAddForm

class ImportAdmin(admin.ModelAdmin):

    form = ImportAdminForm

comment:3 Changed 6 years ago by kmtracey

  • Reporter changed from jdoull@… to Jon

Changed reporter to Jon, no more email address.

If you could put some prose around the debug trace and code snippets to explain what you are trying to do that might help whoever decides to look at this. Perhaps I am just tired but I'm not sure what you are trying to do with these admin defs you have posted and I don't know if that last update is meant to replace what was in the original report or what.

comment:4 Changed 6 years ago by dc

  • Resolution set to invalid
  • Status changed from new to closed

Not a Django bug but yours.

super(ImportAdminForm, self).__init__(self, *args, kwargs)

You are calling bound method __init__ with self as first arg.

The right thing to do:

super(ImportAdminForm, self).__init__(*args, **kwargs)

comment:5 follow-up: Changed 6 years ago by Jon

Thank you! (doh!)

kmtracey - any chance of removing email address from audit note above?
thanks

comment:6 in reply to: ↑ 5 Changed 6 years ago by kmtracey

Replying to Jon:

kmtracey - any chance of removing email address from audit note above?
thanks

Sorry, I don't have any way to do that.

comment:7 Changed 5 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.