This post relates to two separate Django issues that intertwined for
me:
1. Lack of aggregation support in Django's ORM
(I am delighted to see 
http://groups.google.com/group/django-developers/browse_thread/thread/f433edf7b0ebdbcb/
)
2. Django does not use delete() methods for related objects
(as noted previously in:
http://groups.google.com/group/django-users/browse_thread/thread/3e37575e42de86c9/
and
http://groups.google.com/group/django-users/browse_thread/thread/2d1dc42cea162c4b/
)

I would like to hear from others how they are dealing with #1 and what
their thoughts are about #2.

Here goes:
Experimenting with ways to add aggregated database information into my
Django models, I came across a blog entry several weeks ago where the
author (my apologies for not having the reference to cite) said they
used VIEWs as Django Models, simply putting in the SQL code to drop
the table and create a like-named VIEW in sql/model_name as discussed
at 
http://www.djangoproject.com/documentation/0.96/model-api/#providing-initial-sql-data
for providing initial data. I chose to make my VIEW models one-to-one
with the actual Django model that uses the aggregation data, so I can
say event.event_view.capacity_remaining for instance and the
calculation for the number of seats remaining at an event (taking into
account reserved tables, etc) is quietly done by the SQL VIEW, the
Django query just looks up the result. I added empty delete() and
save() methods to the view models to prevent such activities (or so I
thought!) on a non-updatable view.

This approach, as opposed to coding an aggregation query as a method
of a Model, has the advantage of allowing the use of Django's ORM
elegance to do things like EventView.objects.filter(whatever__lookup)
using one database query rather than doing list comprehensions of
method calls and having separate queries for each instance.

Here the fun begins:
When I tried to delete an inline object in the Django Admin by
clearing all the core=True fields, I got an OperationError 1228, VIEW
not UPDATEable.  Argh! I had just discovered that Django does not use
the delete() methods of Models to delete related objects.

My fix for this specific problem was to patch
django.db.models.query.delete_objects() to see if the related model
overrides the delete() method, and if so, use it instead of the
existing batch SQL DELETE approach:

Starting at line 1059:
    # Now delete the actual data
    for cls in ordered_classes:
        seen_objs[cls].reverse()
        pk_list = [pk for pk,instance in seen_objs[cls]]
        # if a related object's class overrides the
django.db.models.Model delete method - use it
        if filter(lambda o: o.__dict__.has_key('delete'),cls.__mro__)
[0].__module__ != 'django.db.models.base':
            map(lambda o: o.delete(),
cls._default_manager.filter(pk__in=pk_list))
        else:
            for offset in range(0, len(pk_list),
GET_ITERATOR_CHUNK_SIZE):
                cursor.execute("DELETE FROM %s WHERE %s IN (%s)" % \
                    (qn(cls._meta.db_table), qn(cls._meta.pk.column),
                    ','.join(['%s' for pk in pk_list[offset:offset
+GET_ITERATOR_CHUNK_SIZE]])),
                    pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE])

It's 4 lines of code - the patch starts with the second comment - plus
indenting within my else clause the original code used for the delete.

Most likely this patch does not cover cases like ManyToManyFields,
etc, I only had time to make the original error go away.

Thoughts? Comments?


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to