Created
December 10, 2012 09:53
-
-
Save MacMaru/4249666 to your computer and use it in GitHub Desktop.
Custom save_m2m for Django Tastypie to pass in request.user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def save_m2m(self, bundle): | |
""" | |
Handles the saving of related M2M data. | |
Due to the way Django works, the M2M data must be handled after the | |
main instance, which is why this isn't a part of the main ``save`` bits. | |
Currently slightly inefficient in that it will clear out the whole | |
relation and recreate the related data as needed. | |
""" | |
for field_name, field_object in self.fields.items(): | |
if not getattr(field_object, 'is_m2m', False): | |
continue | |
if not field_object.attribute: | |
continue | |
if field_object.blank: | |
continue | |
if field_object.readonly: | |
continue | |
# Get the manager. | |
related_mngr = getattr(bundle.obj, field_object.attribute) | |
through_class = getattr(related_mngr, 'through', None) | |
if through_class and not through_class._meta.auto_created: | |
# ManyToMany with an explicit intermediary table. | |
# This should be handled by with specific code, so continue | |
# without modifying anything. | |
# NOTE: this leaves the bundle.needs_save set to True | |
continue | |
related_bundles = bundle.data[field_name] | |
# Remove any relations that were not POSTed | |
if through_class: | |
# ManyToMany with hidden intermediary table. | |
# Use the manager to clear out the relations. | |
related_mngr.clear() | |
else: | |
# OneToMany with foreign keys to this object. | |
# Explicitly delete objects to pass in the user. | |
posted_pks = [b.obj.pk for b in related_bundles if b.obj.pk] | |
if self._meta.pass_request_user_to_django: | |
for obj in related_mngr.for_user( | |
user=bundle.request.user).exclude(pk__in=posted_pks): | |
obj.delete(user=bundle.request.user) | |
else: | |
for obj in related_mngr.all().exclude(pk__in=posted_pks): | |
obj.delete() | |
# Save the posted related objects | |
related_objs = [] | |
for related_bundle in related_bundles: | |
related_objs.append(related_bundle.obj) | |
if related_bundle.needs_save: | |
if self._meta.pass_request_user_to_django: | |
related_bundle.obj.save(user=bundle.request.user) | |
else: | |
related_bundle.obj.save() | |
related_bundle.needs_save = False | |
if through_class: | |
# ManyToMany with hidden intermediary table. Since the save | |
# method on a hidden table can not be overridden we can use the | |
# related_mngr to add. | |
related_mngr.add(*related_objs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment