I ran into an issue today with the Django Admin and I was wondering if this 
was "by design" (in which case I'd like to understand what the rationale 
is) or if it was an actual bug that deserves a ticket.

Here's sample code to illustrate the problem.

# models.py

class MasterModel(models.Model):
    name = models.CharField(max_length=50)
    
    def __unicode__(self):
        return u'%s (Master)' % self.name


class ExternalModel(models.Model):
    master = models.ForeignKey(MasterModel, on_delete=models.DO_NOTHING)
    
    class Meta:
        managed = False


# admin.py

from django.contrib import admin
import models
admin.site.register(models.MasterModel)
admin.site.register(models.ExternalModel)

When I try to delete a MasterModel object in the Admin, I get the following 
exception & traceback:

Environment:

Request Method: POST
Request URL: http://localhost:8000/admin/sample_app/mastermodel/

Django Version: 1.4.2
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'django_on_delete_do_nothing_bug.sample_app')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "D:\Python27\lib\site-packages\django\core\handlers\base.py" in 
get_response
  111.                         response = callback(request, *callback_args, 
**callback_kwargs)
File "D:\Python27\lib\site-packages\django\contrib\admin\options.py" in 
wrapper
  366.                 return self.admin_site.admin_view(view)(*args, 
**kwargs)
File "D:\Python27\lib\site-packages\django\utils\decorators.py" in 
_wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "D:\Python27\lib\site-packages\django\views\decorators\cache.py" in 
_wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "D:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
  196.             return view(request, *args, **kwargs)
File "D:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "D:\Python27\lib\site-packages\django\utils\decorators.py" in 
_wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "D:\Python27\lib\site-packages\django\utils\decorators.py" in 
bound_func
  21.                 return func(self, *args2, **kwargs2)
File "D:\Python27\lib\site-packages\django\contrib\admin\options.py" in 
changelist_view
  1153.                 response = self.response_action(request, 
queryset=cl.get_query_set(request))
File "D:\Python27\lib\site-packages\django\contrib\admin\options.py" in 
response_action
  908.             response = func(self, request, queryset)
File "D:\Python27\lib\site-packages\django\contrib\admin\actions.py" in 
delete_selected
  35.         queryset, opts, request.user, modeladmin.admin_site, using)
File "D:\Python27\lib\site-packages\django\contrib\admin\util.py" in 
get_deleted_objects
  104.     collector.collect(objs)
File "D:\Python27\lib\site-packages\django\contrib\admin\util.py" in collect
  155.             return super(NestedObjects, self).collect(objs, 
source_attr=source_attr, **kwargs)
File "D:\Python27\lib\site-packages\django\db\models\deletion.py" in collect
  175.                     if not sub_objs:
File "D:\Python27\lib\site-packages\django\db\models\query.py" in 
__nonzero__
  130.             iter(self).next()
File "D:\Python27\lib\site-packages\django\db\models\query.py" in 
_result_iter
  118.                 self._fill_cache()
File "D:\Python27\lib\site-packages\django\db\models\query.py" in 
_fill_cache
  892.                     self._result_cache.append(self._iter.next())
File "D:\Python27\lib\site-packages\django\db\models\query.py" in iterator
  291.         for row in compiler.results_iter():
File "D:\Python27\lib\site-packages\django\db\models\sql\compiler.py" in 
results_iter
  763.         for rows in self.execute_sql(MULTI):
File "D:\Python27\lib\site-packages\django\db\models\sql\compiler.py" in 
execute_sql
  818.         cursor.execute(sql, params)
File "D:\Python27\lib\site-packages\django\db\backends\util.py" in execute
  40.             return self.cursor.execute(sql, params)
File "D:\Python27\lib\site-packages\django\db\backends\mysql\base.py" in 
execute
  114.             return self.cursor.execute(query, args)
File "D:\Python27\lib\site-packages\MySQLdb\cursors.py" in execute
  174.             self.errorhandler(self, exc, value)
File "D:\Python27\lib\site-packages\MySQLdb\connections.py" in 
defaulterrorhandler
  36.     raise errorclass, errorvalue

Exception Type: DatabaseError at /admin/sample_app/mastermodel/
Exception Value: (1146, "Table 
'django_bug.sample_app_externalmodeltomaster' doesn't exist")


I would have thought that DO_NOTHING would make Django leave all form of 
error checking up to the DBMS, but apparently the Admin still tries to get 
the list of children that depend on the object being deleted, ignoring the 
DO_NOTHING field. If my understanding of the issue is correct (I apologize 
for not spending the time to open up the Django code and figuring this out 
for sure myself), the Admin is getting all the dependent objects, then 
filters out those for which the ForeignKey is set to DO_NOTHING. Instead, I 
would have expected the ExternalModel table in the example above should 
simply be excluded from that dependency lookup in the first place...

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-users/-/yHW7OawWwZQJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to