# HG changeset patch -- Bitbucket.org # Project django-roa # URL http://bitbucket.org/david/django-roa/overview # User David Larlet # Date 1262819445 -3600 # Node ID 8d453d0b35dd70e17f762151653b2b927677a725 # Parent 3e613d59de365d93951f46ac2c184d834a7577af Solve the many-to-many issue using the "through" argument, which is now required for that type of relation and allows you to customize the URL called in this case. This is no more required to patch Django, yay! Note that I'm still working on the auth/remoteauth duality because of M2M relations between users, groups and permissions. Not easy. --- a/examples/django_roa_client/models.py +++ b/examples/django_roa_client/models.py @@ -92,10 +92,23 @@ class RemotePageWithOverriddenUrls(Model return u'' # overridden by settings +class RemotePageWithRelationsThrough(Model): + title = models.CharField(max_length=50) + remote_page_with_relations = models.ForeignKey("RemotePageWithRelations", blank=True, null=True) + remote_page_with_many_fields = models.ForeignKey("RemotePageWithManyFields", blank=True, null=True) + + def __unicode__(self): + return u'%s (%s)' % (self.title, self.id) + + @staticmethod + def get_resource_url_list(): + return u'http://127.0.0.1:8081/django_roa_server/remotepagewithrelationsthrough/' + + class RemotePageWithRelations(Model): title = models.CharField(max_length=50) remote_page = models.ForeignKey(RemotePage, blank=True, null=True) - remote_page_fields = models.ManyToManyField(RemotePageWithManyFields, blank=True, null=True) + remote_page_fields = models.ManyToManyField(RemotePageWithManyFields, through=RemotePageWithRelationsThrough, blank=True, null=True) def __unicode__(self): return u'%s (%s)' % (self.title, self.id) --- a/examples/django_roa_server/urls.py +++ b/examples/django_roa_server/urls.py @@ -12,7 +12,7 @@ from django_roa_server.handlers import R RemotePageWithManyFieldsCountHandler, RemotePageWithBooleanFieldsCountHandler, \ RemotePageWithCustomSlugCountHandler, RemotePageWithOverriddenUrlsCountHandler, \ RemotePageWithRelationsHandler, RemotePageWithNamedRelationsHandler, \ - RemotePageWithNamedRelationsCountHandler + RemotePageWithNamedRelationsCountHandler, RemotePageWithRelationsThroughHandler remote_pages = Resource(handler=RemotePageHandler) remote_pages_count = Resource(handler=RemotePageCountHandler) @@ -32,6 +32,9 @@ remote_pages_with_overridden_urls_count remote_pages_with_relations = Resource(handler=RemotePageWithRelationsHandler) remote_pages_with_relations_count = Resource(handler=RemotePageWithRelationsHandler) +remote_pages_with_relations_through = Resource(handler=RemotePageWithRelationsThroughHandler) +remote_pages_with_relations_through_count = Resource(handler=RemotePageWithRelationsThroughHandler) + remote_pages_with_named_relations = Resource(handler=RemotePageWithNamedRelationsHandler) remote_pages_with_named_relations_count = Resource(handler=RemotePageWithNamedRelationsCountHandler) @@ -48,6 +51,7 @@ urlpatterns = patterns('', url(r'^django_roa_server/remotepagewithcustomslug/count/$', remote_pages_with_custom_slug_count), url(r'^django_roa_server/remotepagewithoverriddenurls/count/$', remote_pages_with_overridden_urls_count), url(r'^django_roa_server/remotepagewithrelations/count/$', remote_pages_with_relations_count), + url(r'^django_roa_server/remotepagewithrelationsthrough/count/$', remote_pages_with_relations_through_count), url(r'^django_roa_server/remotepagewithnamedrelations/count/$', remote_pages_with_named_relations_count), url(r'^django_roa_server/remotepagewithproxy/count/$', remote_pages_count), @@ -58,6 +62,7 @@ urlpatterns = patterns('', url(r'^django_roa_server/remotepagewithcustomslug/?(?P[-\w]+)?/?$', remote_pages_with_custom_slug), url(r'^django_roa_server/remotepagewithoverriddenurls/?(?P[-\w]+)?/?$', remote_pages_with_overridden_urls), url(r'^django_roa_server/remotepagewithrelations/?(?P\d+)?/?$', remote_pages_with_relations), + url(r'^django_roa_server/remotepagewithrelationsthrough/?(?P\d+)?/?$', remote_pages_with_relations_through), url(r'^django_roa_server/remotepagewithnamedrelations/?(?P\d+)?/?$', remote_pages_with_named_relations), url(r'^django_roa_server/remotepagewithproxy/?(?P\d+)?/?$', remote_pages), --- a/examples/django_roa_server/models.py +++ b/examples/django_roa_server/models.py @@ -56,10 +56,19 @@ class RemotePageWithOverriddenUrls(model return u'%s (%s)' % (self.title, self.id) +class RemotePageWithRelationsThrough(models.Model): + title = models.CharField(max_length=50) + remote_page_with_relations = models.ForeignKey("RemotePageWithRelations", blank=True, null=True) + remote_page_with_many_fields = models.ForeignKey("RemotePageWithManyFields", blank=True, null=True) + + def __unicode__(self): + return u'%s (%s)' % (self.title, self.id) + + class RemotePageWithRelations(models.Model): title = models.CharField(max_length=50) remote_page = models.ForeignKey(RemotePage, blank=True, null=True) - remote_page_fields = models.ManyToManyField(RemotePageWithManyFields, blank=True, null=True) + remote_page_fields = models.ManyToManyField(RemotePageWithManyFields, through=RemotePageWithRelationsThrough, blank=True, null=True) def __unicode__(self): return u'%s (%s)' % (self.title, self.id) --- a/examples/django_roa_server/handlers.py +++ b/examples/django_roa_server/handlers.py @@ -15,7 +15,7 @@ from piston.utils import rc from django_roa_server.models import RemotePage, RemotePageWithManyFields, \ RemotePageWithBooleanFields, RemotePageWithCustomSlug, \ RemotePageWithOverriddenUrls, RemotePageWithRelations, \ - RemotePageWithNamedRelations + RemotePageWithNamedRelations, RemotePageWithRelationsThrough logger = logging.getLogger("django_roa_server") @@ -151,22 +151,6 @@ class ROAHandler(BaseHandler): object.save() - for field in self.model._meta.many_to_many: - field_value = data.get(field.attname, None) - m2m_field = getattr(object, field.attname) - if field_value in (u'', u'None', None): - m2m_field.clear() - logger.debug('M2M relations cleared for "%s"' % ( - unicode(object).encode(settings.DEFAULT_CHARSET), )) - else: - m2m_field.clear() # FIXME: find a clever way? - m2m_convert = field.rel.to._meta.pk.to_python - obj_ids = [m2m_convert(smart_unicode(pk)) for pk in field_value.split(',')] - m2m_field.add(*obj_ids) - logger.debug('M2M relations updated for "%s" with ids %s' % ( - unicode(object).encode(settings.DEFAULT_CHARSET), - obj_ids)) - response = [self.model.objects.get(id=object.id)] #response = [object] logger.debug('Object "%s" modified with %s' % ( @@ -283,6 +267,13 @@ class RemotePageWithRelationsCountHandle model = RemotePageWithRelations +class RemotePageWithRelationsThroughHandler(ROAHandler): + model = RemotePageWithRelationsThrough + +class RemotePageWithRelationsThroughCountHandler(ROACountHandler): + model = RemotePageWithRelationsThrough + + class RemotePageWithNamedRelationsHandler(ROAHandler): model = RemotePageWithNamedRelations --- a/examples/django_roa_client/tests.py +++ b/examples/django_roa_client/tests.py @@ -41,7 +41,8 @@ from django_roa.remoteauth.models import from django_roa_client.models import RemotePage, RemotePageWithManyFields, \ RemotePageWithBooleanFields, RemotePageWithRelations, \ RemotePageWithCustomSlug, RemotePageWithOverriddenUrls, \ - RemotePageWithNamedRelations, RemotePageWithProxy + RemotePageWithNamedRelations, RemotePageWithProxy, \ + RemotePageWithRelationsThrough from django_roa_client.forms import TestForm, RemotePageForm class ROATestCase(TestCase): @@ -381,17 +382,21 @@ class ROARelationsTests(ROATestCase): remote_page = RemotePageWithManyFields.objects.create(char_field=u'A remote page') another_remote_page = RemotePageWithManyFields.objects.create(char_field=u'Another remote page') relations_page = RemotePageWithRelations.objects.create(title=u'A remote relation page') - relations_page.remote_page_fields.add(remote_page) + relations_page_through = RemotePageWithRelationsThrough.objects.create(title=u'A remote relation page through', + remote_page_with_relations=relations_page, + remote_page_with_many_fields=remote_page) self.assertEqual(repr(relations_page.remote_page_fields.all()), '[]') relations_page = RemotePageWithRelations.objects.get(id=relations_page.id) self.assertEqual(repr(relations_page.remote_page_fields.all()), '[]') - relations_page.remote_page_fields.add(another_remote_page) + another_relations_page_through = RemotePageWithRelationsThrough.objects.create(title=u'Another remote relation page through', + remote_page_with_relations=relations_page, + remote_page_with_many_fields=another_remote_page) relations_page = RemotePageWithRelations.objects.get(id=relations_page.id) self.assertEqual(repr(relations_page.remote_page_fields.all()), '[, ]') self.assertEqual(repr(remote_page.remotepagewithrelations_set.all()), '[]') - relations_page.remote_page_fields.remove(remote_page) + relations_page_through.delete() self.assertEqual(repr(relations_page.remote_page_fields.all()), '[]') - relations_page.remote_page_fields.clear() + another_relations_page_through.delete() self.assertEqual(repr(relations_page.remote_page_fields.all()), '[]') relations_page.delete() another_remote_page.delete()