Ticket #11830: save_model_validation_error.diff

File save_model_validation_error.diff, 13.1 KB (added by Nils Fredrik Gjerull, 8 years ago)
  • tests/regressiontests/admin_views/fixtures/admin-views-save-model.xml

     
     1<?xml version="1.0" encoding="utf-8"?>
     2<django-objects version="1.0">
     3    <object pk="100" model="auth.user">
     4        <field type="CharField" name="username">super</field>
     5        <field type="CharField" name="first_name">Super</field>
     6        <field type="CharField" name="last_name">User</field>
     7        <field type="CharField" name="email">super@example.com</field>
     8        <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field>
     9        <field type="BooleanField" name="is_staff">True</field>
     10        <field type="BooleanField" name="is_active">True</field>
     11        <field type="BooleanField" name="is_superuser">True</field>
     12        <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field>
     13        <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field>
     14        <field to="auth.group" name="groups" rel="ManyToManyRel"></field>
     15        <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field>
     16    </object>
     17    <object pk="1" model="admin_views.organization">
     18        <field type="CharField" name="name">Django foundation</field>
     19    </object>
     20    <object pk="2" model="admin_views.organization">
     21        <field type="CharField" name="name">Python foundation</field>
     22    </object>
     23    <object pk="3" model="admin_views.organization">
     24        <field type="CharField" name="name">Zope foundation</field>
     25    </object>
     26    <object pk="4" model="admin_views.organization">
     27        <field type="CharField" name="name">Parrot foundation</field>
     28    </object>
     29    <object pk="1" model="admin_views.dilbert">
     30        <field type="CharField" name="name">Dilbert</field>
     31    </object>
     32    <object pk="1" model="admin_views.role">
     33        <field type="CharField" name="name">Programmer</field>
     34        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">1</field>
     35        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     36    </object>
     37    <object pk="2" model="admin_views.role">
     38        <field type="CharField" name="name">Coffee drinker</field>
     39        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">1</field>
     40        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     41    </object>
     42    <object pk="3" model="admin_views.role">
     43        <field type="CharField" name="name">Programmer</field>
     44        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">2</field>
     45        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     46    </object>
     47    <object pk="4" model="admin_views.role">
     48        <field type="CharField" name="name">Coffee drinker</field>
     49        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">2</field>
     50        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     51    </object>
     52    <object pk="5" model="admin_views.role">
     53        <field type="CharField" name="name">Coffee drinker</field>
     54        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">3</field>
     55        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     56    </object>
     57    <object pk="6" model="admin_views.role">
     58        <field type="CharField" name="name">Programmer</field>
     59        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">3</field>
     60        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     61    </object>
     62    <object pk="7" model="admin_views.role">
     63        <field type="CharField" name="name">Coffee drinker</field>
     64        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">4</field>
     65        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     66    </object>
     67    <object pk="8" model="admin_views.role">
     68        <field type="CharField" name="name">Programmer</field>
     69        <field to="admin_views.organization" name="organization" rel="ManyToOneRel">4</field>
     70        <field to="admin_views.dilbert" name="dilbert" rel="ManyToOneRel">1</field>
     71    </object>
     72</django-objects>
  • tests/regressiontests/admin_views/tests.py

     
    1111from django.contrib.admin.sites import LOGIN_FORM_KEY
    1212from django.contrib.admin.util import quote
    1313from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
     14from django import forms
    1415from django.forms.util import ErrorList
    1516from django.utils import formats
    1617from django.utils.cache import get_max_age
     
    2324    ExternalSubscriber, FooAccount, Gallery, ModelWithStringPrimaryKey, \
    2425    Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \
    2526    Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \
    26     Category, Post, Plot, FunkyTag
     27    Category, Organization, Role, Post, Plot, FunkyTag
    2728
    2829
    2930class AdminViewBasicTest(TestCase):
     
    19351936        self.failUnlessEqual(get_max_age(response), None)
    19361937
    19371938
     1939
     1940
    19381941class ReadonlyTest(TestCase):
    19391942    fixtures = ['admin-views-users.xml']
    19401943
     
    20222025        self.assert_('password' not in adminform.form.errors)
    20232026        self.assertEquals(adminform.form.errors['password2'],
    20242027                          [u"The two password fields didn't match."])
     2028
     2029
     2030class SaveModelTest(TestCase):
     2031    fixtures = ['admin-views-save-model.xml']
     2032
     2033    def setUp(self):
     2034        self.client.login(username='super', password='secret')
     2035        self.post_data = {
     2036            "name": u"Django foundation",
     2037            # inline data
     2038            "role_set-TOTAL_FORMS": "6",
     2039            "role_set-INITIAL_FORMS": "2",
     2040            "role_set-MAX_NUM_FORMS": "0",
     2041            "role_set-0-id": "1",
     2042            "role_set-0-name": u"Programmer",
     2043            "role_set-0-organization": "1",
     2044            "role_set-0-dilbert": "1",
     2045            "role_set-1-id": "2",
     2046            "role_set-1-name": u"Coffee drinker",
     2047            "role_set-1-organization": "1",
     2048            "role_set-1-dilbert": "1",
     2049            "role_set-2-id": "",
     2050            "role_set-2-name": "",
     2051            "role_set-2-organization": "",
     2052            "role_set-2-dilbert": "",
     2053            "role_set-3-id": "",
     2054            "role_set-3-name": "",
     2055            "role_set-3-organization": "",
     2056            "role_set-3-dilbert": "",
     2057            "role_set-4-id": "",
     2058            "role_set-4-name": "",
     2059            "role_set-4-organization": "",
     2060            "role_set-4-dilbert": "",
     2061            "role_set-5-id": "",
     2062            "role_set-5-name": "",
     2063            "role_set-5-organization": "",
     2064            "role_set-5-dilbert": "",
     2065        }
     2066
     2067    def tearDown(self):
     2068        self.client.logout()
     2069
     2070    def test_model_save_method(self):
     2071        """
     2072        Test removing of related objects in the save method on the model.
     2073        """
     2074        org = Organization.objects.get(pk=1)
     2075        self.assertEqual(org.dilberts.count(), 2)
     2076
     2077        try:
     2078            response = self.client.post(
     2079                '/test_admin/admin/admin_views/organization/1/', self.post_data
     2080                )
     2081        except forms.ValidationError:
     2082            self.fail(u'The Model save method should be able to change related\
     2083 model instances without breaking the validation of ModelForms.')
     2084
     2085        self.assertEqual(org.dilberts.count(), 0)
     2086        self.assertEqual(response.status_code, 302) # redirect somewhere
     2087
     2088    def test_admin_save_model_method(self):
     2089        """
     2090        Test removing of related objects in the model_save method
     2091        in the ModelAdmin.
     2092        """
     2093        self.post_data['role_set-0-id'] = '3'
     2094        self.post_data['role_set-0-organization'] = '2'
     2095        self.post_data['role_set-1-id'] = '4'
     2096        self.post_data['role_set-1-organization'] = '2'
     2097        self.post_data['role_set-1-DELETE'] = 'on'
     2098
     2099        org = Organization.objects.get(pk=2)
     2100        self.assertEqual(org.dilberts.count(), 2)
     2101
     2102        try:
     2103            response = self.client.post(
     2104                '/test_admin/admin/admin_views/organization/2/', self.post_data
     2105                )
     2106        except forms.ValidationError:
     2107            self.fail(u'The ModelAdmin save_model method should be able to change related\
     2108 model instances without breaking the validation of ModelForms.')
     2109
     2110        self.assertEqual(org.dilberts.count(), 0)
     2111        self.assertEqual(response.status_code, 302) # redirect somewhere
     2112
     2113    def test_invalid_related_field_choice(self):
     2114        """
     2115        A test to ensure that the model is not changed when an
     2116        invalid role_set-x-id is posted.
     2117        """
     2118        self.post_data['role_set-0-id'] = '100' #Should not exist
     2119        self.post_data['role_set-0-organization'] = '3'
     2120        self.post_data['role_set-1-id'] = '6'
     2121        self.post_data['role_set-1-organization'] = '3'
     2122        self.post_data['role_set-1-DELETE'] = 'on'
     2123
     2124        org = Organization.objects.get(pk=3)
     2125        self.assertEqual(org.dilberts.count(), 2)
     2126
     2127        response = self.client.post(
     2128            '/test_admin/admin/admin_views/organization/3/', self.post_data
     2129        )
     2130
     2131        self.assertEqual(org.dilberts.count(), 2)
     2132        self.assertEqual(response.status_code, 200)
     2133
     2134    def test_change_data(self):
     2135        """
     2136        A test to ensure that the model is not changed when an
     2137        invalid role_set-x-id is posted.
     2138        """
     2139        self.post_data['role_set-0-id'] = '7' #Should not exist
     2140        self.post_data['role_set-0-organization'] = '4'
     2141        self.post_data['role_set-1-id'] = '8'
     2142        self.post_data['role_set-1-name'] = 'Tea drinker'
     2143        self.post_data['role_set-1-organization'] = '4'
     2144
     2145
     2146        org = Organization.objects.get(pk=4)
     2147        self.assertEqual(org.dilberts.count(), 2)
     2148
     2149        response = self.client.post(
     2150            '/test_admin/admin/admin_views/organization/4/', self.post_data
     2151        )
     2152
     2153        role = Role.objects.get(pk=8)
     2154
     2155        # The form is the master
     2156        #self.assertEqual(
     2157        #    role.name, 'Tea drinker',
     2158        #    'The value in the form should override the value set by the model save method (or the ModelAdmin save_model method).')
     2159
     2160        # save_model or save is the master
     2161        self.assertEqual(
     2162            role.name, 'Water drinker',
     2163            'The value in the model save method (or the ModelAdmin save_model method) should override the value in the form.')
     2164
     2165        self.assertEqual(org.dilberts.count(), 2)
     2166        self.assertEqual(response.status_code, 302) # redirect somewhere
  • tests/regressiontests/admin_views/models.py

     
    500500    def get_changelist(self, request, **kwargs):
    501501        return CustomChangeList
    502502
     503
     504class Organization(models.Model):
     505    """
     506    Test the save method
     507    """
     508   
     509    name = models.CharField(max_length=255)
     510    dilberts = models.ManyToManyField(
     511        'Dilbert', through='Role', blank=True
     512    )
     513
     514    def save(self, force_insert=False, force_update=False):
     515        if self.pk == 1: # For test_model_save_method
     516            self.dilberts.clear()
     517        super(Organization, self).save(force_insert, force_update)
     518
     519class Role(models.Model):
     520    name = models.CharField(max_length=255)
     521    organization = models.ForeignKey('Organization')
     522    dilbert = models.ForeignKey('Dilbert')
     523       
     524class Dilbert(models.Model):
     525    name = models.CharField(max_length=255)
     526
     527class RoleInline(admin.TabularInline):
     528    model = Role
     529
     530class OrganizationAdmin(admin.ModelAdmin):
     531    """
     532    Test the save_model method.
     533    """
     534    inlines = (RoleInline,)
     535
     536    def save_model(self, request, obj, form, change):
     537        obj.save()
     538        if obj.pk == 2: # For test_admin_save_model_method
     539            role = Role.objects.get(pk=3)
     540            role.delete()
     541        if obj.pk == 4: # For test_change_data
     542            role = Role.objects.get(pk=8)
     543            role.name = 'Water drinker'
     544            role.save()
     545
     546
    503547class Villain(models.Model):
    504548    name = models.CharField(max_length=100)
    505549
     
    565609    def __unicode__(self):
    566610        return self.name
    567611
     612
    568613admin.site.register(Article, ArticleAdmin)
    569614admin.site.register(CustomArticle, CustomArticleAdmin)
    570615admin.site.register(Section, save_as=True, inlines=[ArticleInline])
     
    588633admin.site.register(Recommender)
    589634admin.site.register(Collector, CollectorAdmin)
    590635admin.site.register(Category, CategoryAdmin)
     636admin.site.register(Organization, OrganizationAdmin)
    591637admin.site.register(Post, PostAdmin)
    592638admin.site.register(Gadget, GadgetAdmin)
    593639admin.site.register(Villain)
Back to Top