Author: zain
Date: 2009-08-03 18:59:05 -0500 (Mon, 03 Aug 2009)
New Revision: 11383

Added:
   django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/urls2.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/
   
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/__init__.py
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/models.py
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
Removed:
   
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/__init__.py
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/models.py
   django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py
Modified:
   django/branches/soc2009/admin-ui/tests/modeltests/expressions/models.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/customadmin.py
   django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/models.py
   django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/tests.py
   django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/tests.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/widgetadmin.py
   django/branches/soc2009/admin-ui/tests/regressiontests/backends/tests.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/fixtures_regress/models.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/models.py
   django/branches/soc2009/admin-ui/tests/regressiontests/mail/tests.py
   
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/tests.py
Log:
[soc2009/admin-ui] Merging up to trunk svn:r11382 into my branch


Modified: 
django/branches/soc2009/admin-ui/tests/modeltests/expressions/models.py
===================================================================
--- django/branches/soc2009/admin-ui/tests/modeltests/expressions/models.py     
2009-08-03 21:18:39 UTC (rev 11382)
+++ django/branches/soc2009/admin-ui/tests/modeltests/expressions/models.py     
2009-08-03 23:59:05 UTC (rev 11383)
@@ -80,4 +80,43 @@
 ...
 FieldError: Joined field references are not permitted in this query
 
+# F expressions can be used to update attributes on single objects
+>>> test_gmbh = Company.objects.get(name='Test GmbH')
+>>> test_gmbh.num_employees
+32
+>>> test_gmbh.num_employees = F('num_employees') + 4
+>>> test_gmbh.save()
+>>> test_gmbh = Company.objects.get(pk=test_gmbh.pk)
+>>> test_gmbh.num_employees
+36
+
+# F expressions cannot be used to update attributes which are foreign keys, or
+# attributes which involve joins.
+>>> test_gmbh.point_of_contact = None
+>>> test_gmbh.save()
+>>> test_gmbh.point_of_contact is None
+True
+>>> test_gmbh.point_of_contact = F('ceo')
+Traceback (most recent call last):
+...
+ValueError: Cannot assign "<django.db.models.expressions.F object at ...>": 
"Company.point_of_contact" must be a "Employee" instance.
+
+>>> test_gmbh.point_of_contact = test_gmbh.ceo
+>>> test_gmbh.save()
+>>> test_gmbh.name = F('ceo__last_name')
+>>> test_gmbh.save()
+Traceback (most recent call last):
+...
+FieldError: Joined field references are not permitted in this query
+
+# F expressions cannot be used to update attributes on objects which do not yet
+# exist in the database
+>>> acme = Company(name='The Acme Widget Co.', num_employees=12, num_chairs=5,
+...     ceo=test_gmbh.ceo)
+>>> acme.num_employees = F('num_employees') + 16
+>>> acme.save()
+Traceback (most recent call last):
+...
+TypeError: int() argument must be a string or a number, not 'ExpressionNode'
+
 """}

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/customadmin.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/customadmin.py
   2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/customadmin.py
   2009-08-03 23:59:05 UTC (rev 11383)
@@ -10,19 +10,19 @@
 class Admin2(admin.AdminSite):
     login_template = 'custom_admin/login.html'
     index_template = 'custom_admin/index.html'
-    
+
     # A custom index view.
     def index(self, request, extra_context=None):
         return super(Admin2, self).index(request, {'foo': '*bar*'})
-    
+
     def get_urls(self):
         return patterns('',
             (r'^my_view/$', self.admin_view(self.my_view)),
         ) + super(Admin2, self).get_urls()
-    
+
     def my_view(self, request):
         return HttpResponse("Django is a magical pony!")
-    
+
 site = Admin2(name="admin2")
 
 site.register(models.Article, models.ArticleAdmin)

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/models.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/models.py    
    2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/models.py    
    2009-08-03 23:59:05 UTC (rev 11383)
@@ -326,7 +326,6 @@
 class PictureAdmin(admin.ModelAdmin):
     pass
 
-
 class Language(models.Model):
     iso = models.CharField(max_length=5, primary_key=True)
     name = models.CharField(max_length=50)
@@ -401,8 +400,25 @@
 class FancyDoodadInline(admin.StackedInline):
     model = FancyDoodad
 
+class Category(models.Model):
+    collector = models.ForeignKey(Collector)
+    order = models.PositiveIntegerField()
+
+    class Meta:
+        ordering = ('order',)
+
+    def __unicode__(self):
+        return u'%s:o%s' % (self.id, self.order)
+
+class CategoryAdmin(admin.ModelAdmin):
+    list_display = ('id', 'collector', 'order')
+    list_editable = ('order',)
+
+class CategoryInline(admin.StackedInline):
+    model = Category
+
 class CollectorAdmin(admin.ModelAdmin):
-    inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, 
FancyDoodadInline]
+    inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, 
FancyDoodadInline, CategoryInline]
 
 admin.site.register(Article, ArticleAdmin)
 admin.site.register(CustomArticle, CustomArticleAdmin)
@@ -426,6 +442,7 @@
 admin.site.register(Recommendation, RecommendationAdmin)
 admin.site.register(Recommender)
 admin.site.register(Collector, CollectorAdmin)
+admin.site.register(Category, CategoryAdmin)
 
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor 
ChapterXtra2.
 # That way we cover all four cases:

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/tests.py
===================================================================
--- django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/tests.py 
2009-08-03 21:18:39 UTC (rev 11382)
+++ django/branches/soc2009/admin-ui/tests/regressiontests/admin_views/tests.py 
2009-08-03 23:59:05 UTC (rev 11383)
@@ -10,13 +10,15 @@
 from django.contrib.admin.sites import LOGIN_FORM_KEY
 from django.contrib.admin.util import quote
 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
+from django.utils.cache import get_max_age
 from django.utils.html import escape
 
 # local test models
 from models import Article, BarAccount, CustomArticle, EmptyModel, \
     ExternalSubscriber, FooAccount, Gallery, ModelWithStringPrimaryKey, \
     Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \
-    Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit
+    Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \
+    Category
 
 try:
     set
@@ -203,6 +205,11 @@
         response = self.client.get('/test_admin/%s/admin_views/thing/' % 
self.urlbit, {'color__id__exact': 'StringNotInteger!'})
         self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' 
% self.urlbit)
 
+    def testLogoutAndPasswordChangeURLs(self):
+        response = self.client.get('/test_admin/%s/admin_views/article/' % 
self.urlbit)
+        self.failIf('<a href="/test_admin/%s/logout/">' % self.urlbit not in 
response.content)
+        self.failIf('<a href="/test_admin/%s/password_change/">' % self.urlbit 
not in response.content)
+
     def testNamedGroupFieldChoicesChangeList(self):
         """
         Ensures the admin changelist shows correct values in the relevant 
column
@@ -921,6 +928,45 @@
 
         self.failUnlessEqual(Person.objects.get(name="John Mauchly").alive, 
False)
 
+    def test_list_editable_ordering(self):
+        collector = Collector.objects.create(id=1, name="Frederick Clegg")
+
+        Category.objects.create(id=1, order=1, collector=collector)
+        Category.objects.create(id=2, order=2, collector=collector)
+        Category.objects.create(id=3, order=0, collector=collector)
+        Category.objects.create(id=4, order=0, collector=collector)
+
+        # NB: The order values must be changed so that the items are reordered.
+        data = {
+            "form-TOTAL_FORMS": "4",
+            "form-INITIAL_FORMS": "4",
+
+            "form-0-order": "14",
+            "form-0-id": "1",
+            "form-0-collector": "1",
+
+            "form-1-order": "13",
+            "form-1-id": "2",
+            "form-1-collector": "1",
+
+            "form-2-order": "1",
+            "form-2-id": "3",
+            "form-2-collector": "1",
+
+            "form-3-order": "0",
+            "form-3-id": "4",
+            "form-3-collector": "1",
+        }
+        response = self.client.post('/test_admin/admin/admin_views/category/', 
data)
+        # Successful post will redirect
+        self.failUnlessEqual(response.status_code, 302)
+
+        # Check that the order values have been applied to the right objects
+        self.failUnlessEqual(Category.objects.get(id=1).order, 14)
+        self.failUnlessEqual(Category.objects.get(id=2).order, 13)
+        self.failUnlessEqual(Category.objects.get(id=3).order, 1)
+        self.failUnlessEqual(Category.objects.get(id=4).order, 0)
+
 class AdminSearchTest(TestCase):
     fixtures = ['admin-views-users','multiple-child-classes']
 
@@ -1254,11 +1300,24 @@
             "fancydoodad_set-2-owner": "1",
             "fancydoodad_set-2-name": "",
             "fancydoodad_set-2-expensive": "on",
+
+            "category_set-TOTAL_FORMS": "3",
+            "category_set-INITIAL_FORMS": "0",
+            "category_set-0-order": "",
+            "category_set-0-id": "",
+            "category_set-0-collector": "1",
+            "category_set-1-order": "",
+            "category_set-1-id": "",
+            "category_set-1-collector": "1",
+            "category_set-2-order": "",
+            "category_set-2-id": "",
+            "category_set-2-collector": "1",
         }
 
         result = self.client.login(username='super', password='secret')
         self.failUnlessEqual(result, True)
-        Collector(pk=1,name='John Fowles').save()
+        self.collector = Collector(pk=1,name='John Fowles')
+        self.collector.save()
 
     def tearDown(self):
         self.client.logout()
@@ -1419,3 +1478,131 @@
         self.failUnlessEqual(response.status_code, 302)
         self.failUnlessEqual(FancyDoodad.objects.count(), 1)
         self.failUnlessEqual(FancyDoodad.objects.all()[0].name, "Fancy Doodad 
1 Updated")
+
+    def test_ordered_inline(self):
+        """Check that an inline with an editable ordering fields is
+        updated correctly. Regression for #10922"""
+        # Create some objects with an initial ordering
+        Category.objects.create(id=1, order=1, collector=self.collector)
+        Category.objects.create(id=2, order=2, collector=self.collector)
+        Category.objects.create(id=3, order=0, collector=self.collector)
+        Category.objects.create(id=4, order=0, collector=self.collector)
+
+        # NB: The order values must be changed so that the items are reordered.
+        self.post_data.update({
+            "name": "Frederick Clegg",
+
+            "category_set-TOTAL_FORMS": "7",
+            "category_set-INITIAL_FORMS": "4",
+
+            "category_set-0-order": "14",
+            "category_set-0-id": "1",
+            "category_set-0-collector": "1",
+
+            "category_set-1-order": "13",
+            "category_set-1-id": "2",
+            "category_set-1-collector": "1",
+
+            "category_set-2-order": "1",
+            "category_set-2-id": "3",
+            "category_set-2-collector": "1",
+
+            "category_set-3-order": "0",
+            "category_set-3-id": "4",
+            "category_set-3-collector": "1",
+
+            "category_set-4-order": "",
+            "category_set-4-id": "",
+            "category_set-4-collector": "1",
+
+            "category_set-5-order": "",
+            "category_set-5-id": "",
+            "category_set-5-collector": "1",
+
+            "category_set-6-order": "",
+            "category_set-6-id": "",
+            "category_set-6-collector": "1",
+        })
+        response = 
self.client.post('/test_admin/admin/admin_views/collector/1/', self.post_data)
+        # Successful post will redirect
+        self.failUnlessEqual(response.status_code, 302)
+
+        # Check that the order values have been applied to the right objects
+        self.failUnlessEqual(self.collector.category_set.count(), 4)
+        self.failUnlessEqual(Category.objects.get(id=1).order, 14)
+        self.failUnlessEqual(Category.objects.get(id=2).order, 13)
+        self.failUnlessEqual(Category.objects.get(id=3).order, 1)
+        self.failUnlessEqual(Category.objects.get(id=4).order, 0)
+
+
+class NeverCacheTests(TestCase):
+    fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 
'admin-views-fabrics.xml']
+
+    def setUp(self):
+        self.client.login(username='super', password='secret')
+
+    def tearDown(self):
+        self.client.logout()
+
+    def testAdminIndex(self):
+        "Check the never-cache status of the main index"
+        response = self.client.get('/test_admin/admin/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testAppIndex(self):
+        "Check the never-cache status of an application index"
+        response = self.client.get('/test_admin/admin/admin_views/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testModelIndex(self):
+        "Check the never-cache status of a model index"
+        response = self.client.get('/test_admin/admin/admin_views/fabric/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testModelAdd(self):
+        "Check the never-cache status of a model add page"
+        response = self.client.get('/test_admin/admin/admin_views/fabric/add/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testModelView(self):
+        "Check the never-cache status of a model edit page"
+        response = self.client.get('/test_admin/admin/admin_views/section/1/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testModelHistory(self):
+        "Check the never-cache status of a model history page"
+        response = 
self.client.get('/test_admin/admin/admin_views/section/1/history/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testModelDelete(self):
+        "Check the never-cache status of a model delete page"
+        response = 
self.client.get('/test_admin/admin/admin_views/section/1/delete/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testLogin(self):
+        "Check the never-cache status of login views"
+        self.client.logout()
+        response = self.client.get('/test_admin/admin/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testLogout(self):
+        "Check the never-cache status of logout view"
+        response = self.client.get('/test_admin/admin/logout/')
+        self.failUnlessEqual(get_max_age(response), 0)
+
+    def testPasswordChange(self):
+        "Check the never-cache status of the password change view"
+        self.client.logout()
+        response = self.client.get('/test_admin/password_change/')
+        self.failUnlessEqual(get_max_age(response), None)
+
+    def testPasswordChangeDone(self):
+        "Check the never-cache status of the password change done view"
+        response = self.client.get('/test_admin/admin/password_change/done/')
+        self.failUnlessEqual(get_max_age(response), None)
+
+    def testJsi18n(self):
+        "Check the never-cache status of the Javascript i18n view"
+        response = self.client.get('/test_admin/jsi18n/')
+        self.failUnlessEqual(get_max_age(response), None)
+

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/tests.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/tests.py   
    2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/tests.py   
    2009-08-03 23:59:05 UTC (rev 11383)
@@ -115,6 +115,7 @@
 
 class AdminForeignKeyWidgetChangeList(DjangoTestCase):
     fixtures = ["admin-widgets-users.xml"]
+    admin_root = '/widget_admin'
 
     def setUp(self):
         self.client.login(username="super", password="secret")
@@ -123,5 +124,9 @@
         self.client.logout()
 
     def test_changelist_foreignkey(self):
-        response = self.client.get('/widget_admin/admin_widgets/car/')
-        self.failUnless('/widget_admin/auth/user/add/' in response.content)
+        response = self.client.get('%s/admin_widgets/car/' % self.admin_root)
+        self.failUnless('%s/auth/user/add/' % self.admin_root in 
response.content)
+
+class OldAdminForeignKeyWidgetChangeList(AdminForeignKeyWidgetChangeList):
+    urls = 'regressiontests.admin_widgets.urls2'
+    admin_root = '/deep/down/admin'

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/urls2.py 
(from rev 11382, django/trunk/tests/regressiontests/admin_widgets/urls2.py)
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/urls2.py   
                            (rev 0)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/urls2.py   
    2009-08-03 23:59:05 UTC (rev 11383)
@@ -0,0 +1,7 @@
+
+from django.conf.urls.defaults import *
+import widgetadmin
+
+urlpatterns = patterns('',
+    (r'^deep/down/admin/(.*)', widgetadmin.site.root),
+)

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/widgetadmin.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/widgetadmin.py
 2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/admin_widgets/widgetadmin.py
 2009-08-03 23:59:05 UTC (rev 11383)
@@ -19,7 +19,7 @@
             return db_field.formfield(**kwargs)
         return super(CarTireAdmin, self).formfield_for_foreignkey(db_field, 
request, **kwargs)
 
-site = WidgetAdmin()
+site = WidgetAdmin(name='widget-admin')
 
 site.register(models.User)
 site.register(models.Car, CarAdmin)

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/backends/tests.py
===================================================================
--- django/branches/soc2009/admin-ui/tests/regressiontests/backends/tests.py    
2009-08-03 21:18:39 UTC (rev 11382)
+++ django/branches/soc2009/admin-ui/tests/regressiontests/backends/tests.py    
2009-08-03 23:59:05 UTC (rev 11383)
@@ -17,7 +17,22 @@
             return True
         else:
             return True
+            
+class LongString(unittest.TestCase):
 
+    def test_long_string(self):
+        # If the backend is Oracle, test that we can save a text longer
+        # than 4000 chars and read it properly
+        if settings.DATABASE_ENGINE == 'oracle':
+            c = connection.cursor()
+            c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
+            long_str = ''.join([unicode(x) for x in xrange(4000)])
+            c.execute('INSERT INTO ltext VALUES (%s)',[long_str])
+            c.execute('SELECT text FROM ltext')
+            row = c.fetchone()
+            c.execute('DROP TABLE ltext')
+            self.assertEquals(long_str, row[0].read())
+
 def connection_created_test(sender, **kwargs):
     print 'connection_created signal'
 

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/fixtures_regress/models.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/fixtures_regress/models.py
   2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/fixtures_regress/models.py
   2009-08-03 23:59:05 UTC (rev 11383)
@@ -54,7 +54,7 @@
 class Child(Parent):
     data = models.CharField(max_length=10)
 
-# Models to regresison check #7572
+# Models to regression test #7572
 class Channel(models.Model):
     name = models.CharField(max_length=255)
 
@@ -65,6 +65,14 @@
     class Meta:
         ordering = ('id',)
 
+# Models to regression test #11428
+class Widget(models.Model):
+    name = models.CharField(max_length=255)
+
+class WidgetProxy(Widget):
+    class Meta:
+        proxy = True
+
 __test__ = {'API_TESTS':"""
 >>> from django.core import management
 
@@ -170,4 +178,18 @@
 >>> management.call_command('dumpdata', 'fixtures_regress.animal', 
 >>> format='json')
 [{"pk": 1, "model": "fixtures_regress.animal", "fields": {"count": 3, 
"weight": 1.2, "name": "Lion", "latin_name": "Panthera leo"}}, {"pk": 2, 
"model": "fixtures_regress.animal", "fields": {"count": 2, "weight": 2.29..., 
"name": "Platypus", "latin_name": "Ornithorhynchus anatinus"}}, {"pk": 10, 
"model": "fixtures_regress.animal", "fields": {"count": 42, "weight": 1.2, 
"name": "Emu", "latin_name": "Dromaius novaehollandiae"}}]
 
+###############################################
+# Regression for #11428 - Proxy models aren't included
+# when you run dumpdata over an entire app
+
+# Flush out the database first
+>>> management.call_command('reset', 'fixtures_regress', interactive=False, 
verbosity=0)
+
+# Create an instance of the concrete class
+>>> Widget(name='grommet').save()
+
+# Dump data for the entire app. The proxy class shouldn't be included
+>>> management.call_command('dumpdata', 'fixtures_regress', format='json')
+[{"pk": 1, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]
+
 """}

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures
 (from rev 11382, 
django/trunk/tests/regressiontests/m2m_through_regress/fixtures)

Deleted: 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
===================================================================
--- 
django/trunk/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
    2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
        2009-08-03 23:59:05 UTC (rev 11383)
@@ -1,34 +0,0 @@
-[
-    {
-        "pk": "1",
-        "model": "m2m_through_regress.person",
-        "fields": {
-            "name": "Guido"
-        }
-    },
-    {
-        "pk": "1",
-        "model": "auth.user",
-        "fields": {
-             "username": "Guido",
-             "email": "[email protected]",
-             "password": "abcde"
-        }
-    },
-    {
-        "pk": "1",
-        "model": "m2m_through_regress.group",
-        "fields": {
-            "name": "Python Core Group"
-        }
-    },
-    {
-        "pk": "1",
-        "model": "m2m_through_regress.usermembership",
-        "fields": {
-            "user": "1",
-            "group": "1",
-            "price": "100"
-        }
-    }
-]
\ No newline at end of file

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
 (from rev 11382, 
django/trunk/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json)
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
                                (rev 0)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/fixtures/m2m_through.json
        2009-08-03 23:59:05 UTC (rev 11383)
@@ -0,0 +1,34 @@
+[
+    {
+        "pk": "1",
+        "model": "m2m_through_regress.person",
+        "fields": {
+            "name": "Guido"
+        }
+    },
+    {
+        "pk": "1",
+        "model": "auth.user",
+        "fields": {
+             "username": "Guido",
+             "email": "[email protected]",
+             "password": "abcde"
+        }
+    },
+    {
+        "pk": "1",
+        "model": "m2m_through_regress.group",
+        "fields": {
+            "name": "Python Core Group"
+        }
+    },
+    {
+        "pk": "1",
+        "model": "m2m_through_regress.usermembership",
+        "fields": {
+            "user": "1",
+            "group": "1",
+            "price": "100"
+        }
+    }
+]
\ No newline at end of file

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/models.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/models.py
        2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/m2m_through_regress/models.py
        2009-08-03 23:59:05 UTC (rev 11383)
@@ -12,7 +12,9 @@
     def __unicode__(self):
         return "%s is a member of %s" % (self.person.name, self.group.name)
 
+# using custom id column to test ticket #11107
 class UserMembership(models.Model):
+    id = models.AutoField(db_column='usermembership_id', primary_key=True)
     user = models.ForeignKey(User)
     group = models.ForeignKey('Group')
     price = models.IntegerField(default=100)
@@ -196,4 +198,12 @@
 # Flush the database, just to make sure we can.
 >>> management.call_command('flush', verbosity=0, interactive=False)
 
+## Regression test for #11107
+Ensure that sequences on m2m_through tables are being created for the through
+model, not for a phantom auto-generated m2m table.
+
+>>> management.call_command('loaddata', 'm2m_through', verbosity=0)
+>>> management.call_command('dumpdata', 'm2m_through_regress', format='json')
+[{"pk": 1, "model": "m2m_through_regress.usermembership", "fields": {"price": 
100, "group": 1, "user": 1}}, {"pk": 1, "model": "m2m_through_regress.person", 
"fields": {"name": "Guido"}}, {"pk": 1, "model": "m2m_through_regress.group", 
"fields": {"name": "Python Core Group"}}]
+
 """}

Modified: django/branches/soc2009/admin-ui/tests/regressiontests/mail/tests.py
===================================================================
--- django/branches/soc2009/admin-ui/tests/regressiontests/mail/tests.py        
2009-08-03 21:18:39 UTC (rev 11382)
+++ django/branches/soc2009/admin-ui/tests/regressiontests/mail/tests.py        
2009-08-03 23:59:05 UTC (rev 11383)
@@ -90,8 +90,8 @@
 
 # Make sure we can manually set the From header (#9214)
 
->>> email = EmailMessage('Subject', 'Content', '[email protected]', 
['[email protected]'], headers={'From': '[email protected]'}) 
->>> message = email.message() 
+>>> email = EmailMessage('Subject', 'Content', '[email protected]', 
['[email protected]'], headers={'From': '[email protected]'})
+>>> message = email.message()
 >>> message['From']
 '[email protected]'
 
@@ -115,8 +115,7 @@
 Date: Fri, 09 Nov 2001 01:08:47 -0000
 Message-ID: foo
 ...
-Content-Type: multipart/alternative; boundary="..."
-MIME-Version: 1.0
+Content-Type: multipart/alternative;...
 ...
 Content-Type: text/plain; charset="utf-8"
 MIME-Version: 1.0

Copied: django/branches/soc2009/admin-ui/tests/regressiontests/servers (from 
rev 11382, django/trunk/tests/regressiontests/servers)


Property changes on: 
django/branches/soc2009/admin-ui/tests/regressiontests/servers
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Deleted: 
django/branches/soc2009/admin-ui/tests/regressiontests/servers/__init__.py
===================================================================

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/servers/__init__.py 
(from rev 11382, django/trunk/tests/regressiontests/servers/__init__.py)
===================================================================

Deleted: 
django/branches/soc2009/admin-ui/tests/regressiontests/servers/models.py
===================================================================

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/servers/models.py (from 
rev 11382, django/trunk/tests/regressiontests/servers/models.py)
===================================================================

Deleted: django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py
===================================================================
--- django/trunk/tests/regressiontests/servers/tests.py 2009-08-03 21:18:39 UTC 
(rev 11382)
+++ django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py     
2009-08-03 23:59:05 UTC (rev 11383)
@@ -1,67 +0,0 @@
-"""
-Tests for django.core.servers.
-"""
-
-import os
-
-import django
-from django.test import TestCase
-from django.core.handlers.wsgi import WSGIHandler
-from django.core.servers.basehttp import AdminMediaHandler
-
-
-class AdminMediaHandlerTests(TestCase):
-
-    def setUp(self):
-        self.admin_media_file_path = \
-            os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
-        self.handler = AdminMediaHandler(WSGIHandler())
-
-    def test_media_urls(self):
-        """
-        Tests that URLs that look like absolute file paths after the
-        settings.ADMIN_MEDIA_PREFIX don't turn into absolute file paths.
-        """
-        # Cases that should work on all platforms.
-        data = (
-            ('/media/css/base.css', ('css', 'base.css')),
-        )
-        # Cases that should raise an exception.
-        bad_data = ()
-
-        # Add platform-specific cases.
-        if os.sep == '/':
-            data += (
-                # URL, tuple of relative path parts.
-                ('/media/\\css/base.css', ('\\css', 'base.css')),
-            )
-            bad_data += (
-                '/media//css/base.css',
-                '/media////css/base.css',
-                '/media/../css/base.css',
-            )
-        elif os.sep == '\\':
-            bad_data += (
-                '/media/C:\css/base.css',
-                '/media//\\css/base.css',
-                '/media/\\css/base.css',
-                '/media/\\\\css/base.css'
-            )
-        for url, path_tuple in data:
-            try:
-                output = self.handler.file_path(url)
-            except ValueError:
-                self.fail("Got a ValueError exception, but wasn't expecting"
-                          " one. URL was: %s" % url)
-            rel_path = os.path.join(*path_tuple)
-            desired = os.path.normcase(
-                os.path.join(self.admin_media_file_path, rel_path))
-            self.assertEqual(output, desired,
-                "Got: %s, Expected: %s, URL was: %s" % (output, desired, url))
-        for url in bad_data:
-            try:
-                output = self.handler.file_path(url)
-            except ValueError:
-                continue
-            self.fail('URL: %s should have caused a ValueError exception.'
-                      % url)

Copied: django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py 
(from rev 11382, django/trunk/tests/regressiontests/servers/tests.py)
===================================================================
--- django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py     
                        (rev 0)
+++ django/branches/soc2009/admin-ui/tests/regressiontests/servers/tests.py     
2009-08-03 23:59:05 UTC (rev 11383)
@@ -0,0 +1,67 @@
+"""
+Tests for django.core.servers.
+"""
+
+import os
+
+import django
+from django.test import TestCase
+from django.core.handlers.wsgi import WSGIHandler
+from django.core.servers.basehttp import AdminMediaHandler
+
+
+class AdminMediaHandlerTests(TestCase):
+
+    def setUp(self):
+        self.admin_media_file_path = \
+            os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
+        self.handler = AdminMediaHandler(WSGIHandler())
+
+    def test_media_urls(self):
+        """
+        Tests that URLs that look like absolute file paths after the
+        settings.ADMIN_MEDIA_PREFIX don't turn into absolute file paths.
+        """
+        # Cases that should work on all platforms.
+        data = (
+            ('/media/css/base.css', ('css', 'base.css')),
+        )
+        # Cases that should raise an exception.
+        bad_data = ()
+
+        # Add platform-specific cases.
+        if os.sep == '/':
+            data += (
+                # URL, tuple of relative path parts.
+                ('/media/\\css/base.css', ('\\css', 'base.css')),
+            )
+            bad_data += (
+                '/media//css/base.css',
+                '/media////css/base.css',
+                '/media/../css/base.css',
+            )
+        elif os.sep == '\\':
+            bad_data += (
+                '/media/C:\css/base.css',
+                '/media//\\css/base.css',
+                '/media/\\css/base.css',
+                '/media/\\\\css/base.css'
+            )
+        for url, path_tuple in data:
+            try:
+                output = self.handler.file_path(url)
+            except ValueError:
+                self.fail("Got a ValueError exception, but wasn't expecting"
+                          " one. URL was: %s" % url)
+            rel_path = os.path.join(*path_tuple)
+            desired = os.path.normcase(
+                os.path.join(self.admin_media_file_path, rel_path))
+            self.assertEqual(output, desired,
+                "Got: %s, Expected: %s, URL was: %s" % (output, desired, url))
+        for url in bad_data:
+            try:
+                output = self.handler.file_path(url)
+            except ValueError:
+                continue
+            self.fail('URL: %s should have caused a ValueError exception.'
+                      % url)

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py
 (from rev 11382, 
django/trunk/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py)
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py
                               (rev 0)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/included_namespace_urls.py
       2009-08-03 23:59:05 UTC (rev 11383)
@@ -0,0 +1,13 @@
+from django.conf.urls.defaults import *
+from namespace_urls import URLObject
+
+testobj3 = URLObject('testapp', 'test-ns3')
+
+urlpatterns = patterns('regressiontests.urlpatterns_reverse.views',
+    url(r'^normal/$', 'empty_view', name='inc-normal-view'),
+    url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', 
name='inc-normal-view'),
+
+    (r'^test3/', include(testobj3.urls)),
+    (r'^ns-included3/', 
include('regressiontests.urlpatterns_reverse.included_urls', 
namespace='inc-ns3')),
+)
+

Copied: 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
 (from rev 11382, 
django/trunk/tests/regressiontests/urlpatterns_reverse/namespace_urls.py)
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
                                (rev 0)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
        2009-08-03 23:59:05 UTC (rev 11383)
@@ -0,0 +1,38 @@
+from django.conf.urls.defaults import *
+
+class URLObject(object):
+    def __init__(self, app_name, namespace):
+        self.app_name = app_name
+        self.namespace = namespace
+
+    def urls(self):
+        return patterns('',
+            url(r'^inner/$', 'empty_view', name='urlobject-view'),
+            url(r'^inner/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', 
name='urlobject-view'),
+        ), self.app_name, self.namespace
+    urls = property(urls)
+
+testobj1 = URLObject('testapp', 'test-ns1')
+testobj2 = URLObject('testapp', 'test-ns2')
+default_testobj = URLObject('testapp', 'testapp')
+
+otherobj1 = URLObject('nodefault', 'other-ns1')
+otherobj2 = URLObject('nodefault', 'other-ns2')
+
+urlpatterns = patterns('regressiontests.urlpatterns_reverse.views',
+    url(r'^normal/$', 'empty_view', name='normal-view'),
+    url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', 
name='normal-view'),
+
+    (r'^test1/', include(testobj1.urls)),
+    (r'^test2/', include(testobj2.urls)),
+    (r'^default/', include(default_testobj.urls)),
+
+    (r'^other1/', include(otherobj1.urls)),
+    (r'^other2/', include(otherobj2.urls)),
+
+    (r'^ns-included1/', 
include('regressiontests.urlpatterns_reverse.included_namespace_urls', 
namespace='inc-ns1')),
+    (r'^ns-included2/', 
include('regressiontests.urlpatterns_reverse.included_namespace_urls', 
namespace='inc-ns2')),
+
+    (r'^included/', 
include('regressiontests.urlpatterns_reverse.included_namespace_urls')),
+
+)

Modified: 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/tests.py
===================================================================
--- 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/tests.py
 2009-08-03 21:18:39 UTC (rev 11382)
+++ 
django/branches/soc2009/admin-ui/tests/regressiontests/urlpatterns_reverse/tests.py
 2009-08-03 23:59:05 UTC (rev 11383)
@@ -158,4 +158,84 @@
         res = redirect('/foo/')
         self.assertEqual(res['Location'], '/foo/')
         res = redirect('http://example.com/')
-        self.assertEqual(res['Location'], 'http://example.com/')
\ No newline at end of file
+        self.assertEqual(res['Location'], 'http://example.com/')
+
+
+class NamespaceTests(TestCase):
+    urls = 'regressiontests.urlpatterns_reverse.namespace_urls'
+
+    def test_ambiguous_object(self):
+        "Names deployed via dynamic URL objects that require namespaces can't 
be resolved"
+        self.assertRaises(NoReverseMatch, reverse, 'urlobject-view')
+        self.assertRaises(NoReverseMatch, reverse, 'urlobject-view', 
args=[37,42])
+        self.assertRaises(NoReverseMatch, reverse, 'urlobject-view', 
kwargs={'arg1':42, 'arg2':37})
+
+    def test_ambiguous_urlpattern(self):
+        "Names deployed via dynamic URL objects that require namespaces can't 
be resolved"
+        self.assertRaises(NoReverseMatch, reverse, 'inner-nothing')
+        self.assertRaises(NoReverseMatch, reverse, 'inner-nothing', 
args=[37,42])
+        self.assertRaises(NoReverseMatch, reverse, 'inner-nothing', 
kwargs={'arg1':42, 'arg2':37})
+
+    def test_non_existent_namespace(self):
+        "Non-existent namespaces raise errors"
+        self.assertRaises(NoReverseMatch, reverse, 'blahblah:urlobject-view')
+        self.assertRaises(NoReverseMatch, reverse, 
'test-ns1:blahblah:urlobject-view')
+
+    def test_normal_name(self):
+        "Normal lookups work as expected"
+        self.assertEquals('/normal/', reverse('normal-view'))
+        self.assertEquals('/normal/37/42/', reverse('normal-view', 
args=[37,42]))
+        self.assertEquals('/normal/42/37/', reverse('normal-view', 
kwargs={'arg1':42, 'arg2':37}))
+
+    def test_simple_included_name(self):
+        "Normal lookups work on names included from other patterns"
+        self.assertEquals('/included/normal/', reverse('inc-normal-view'))
+        self.assertEquals('/included/normal/37/42/', 
reverse('inc-normal-view', args=[37,42]))
+        self.assertEquals('/included/normal/42/37/', 
reverse('inc-normal-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_namespace_object(self):
+        "Dynamic URL objects can be found using a namespace"
+        self.assertEquals('/test1/inner/', reverse('test-ns1:urlobject-view'))
+        self.assertEquals('/test1/inner/37/42/', 
reverse('test-ns1:urlobject-view', args=[37,42]))
+        self.assertEquals('/test1/inner/42/37/', 
reverse('test-ns1:urlobject-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_embedded_namespace_object(self):
+        "Namespaces can be installed anywhere in the URL pattern tree"
+        self.assertEquals('/included/test3/inner/', 
reverse('test-ns3:urlobject-view'))
+        self.assertEquals('/included/test3/inner/37/42/', 
reverse('test-ns3:urlobject-view', args=[37,42]))
+        self.assertEquals('/included/test3/inner/42/37/', 
reverse('test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_namespace_pattern(self):
+        "Namespaces can be applied to include()'d urlpatterns"
+        self.assertEquals('/ns-included1/normal/', 
reverse('inc-ns1:inc-normal-view'))
+        self.assertEquals('/ns-included1/normal/37/42/', 
reverse('inc-ns1:inc-normal-view', args=[37,42]))
+        self.assertEquals('/ns-included1/normal/42/37/', 
reverse('inc-ns1:inc-normal-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_multiple_namespace_pattern(self):
+        "Namespaces can be embedded"
+        self.assertEquals('/ns-included1/test3/inner/', 
reverse('inc-ns1:test-ns3:urlobject-view'))
+        self.assertEquals('/ns-included1/test3/inner/37/42/', 
reverse('inc-ns1:test-ns3:urlobject-view', args=[37,42]))
+        self.assertEquals('/ns-included1/test3/inner/42/37/', 
reverse('inc-ns1:test-ns3:urlobject-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_app_lookup_object(self):
+        "A default application namespace can be used for lookup"
+        self.assertEquals('/default/inner/', reverse('testapp:urlobject-view'))
+        self.assertEquals('/default/inner/37/42/', 
reverse('testapp:urlobject-view', args=[37,42]))
+        self.assertEquals('/default/inner/42/37/', 
reverse('testapp:urlobject-view', kwargs={'arg1':42, 'arg2':37}))
+
+    def test_app_lookup_object_with_default(self):
+        "A default application namespace is sensitive to the 'current' app can 
be used for lookup"
+        self.assertEquals('/included/test3/inner/', 
reverse('testapp:urlobject-view', current_app='test-ns3'))
+        self.assertEquals('/included/test3/inner/37/42/', 
reverse('testapp:urlobject-view', args=[37,42], current_app='test-ns3'))
+        self.assertEquals('/included/test3/inner/42/37/', 
reverse('testapp:urlobject-view', kwargs={'arg1':42, 'arg2':37}, 
current_app='test-ns3'))
+
+    def test_app_lookup_object_without_default(self):
+        "An application namespace without a default is sensitive to the 
'current' app can be used for lookup"
+        self.assertEquals('/other2/inner/', 
reverse('nodefault:urlobject-view'))
+        self.assertEquals('/other2/inner/37/42/', 
reverse('nodefault:urlobject-view', args=[37,42]))
+        self.assertEquals('/other2/inner/42/37/', 
reverse('nodefault:urlobject-view', kwargs={'arg1':42, 'arg2':37}))
+
+        self.assertEquals('/other1/inner/', 
reverse('nodefault:urlobject-view', current_app='other-ns1'))
+        self.assertEquals('/other1/inner/37/42/', 
reverse('nodefault:urlobject-view', args=[37,42], current_app='other-ns1'))
+        self.assertEquals('/other1/inner/42/37/', 
reverse('nodefault:urlobject-view', kwargs={'arg1':42, 'arg2':37}, 
current_app='other-ns1'))
+


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

Reply via email to