Django

Code

Changeset 8884

Show
Ignore:
Timestamp:
09/02/08 19:09:33 (3 months ago)
Author:
mtredinnick
Message:

Fixed #8669 -- Use a consistent version of create() across the board for
model/field instance creation. Based on a patch from Richard Davies.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/contenttypes/generic.py

    r8855 r8884  
    272272            kwargs[self.content_type_field_name] = self.content_type 
    273273            kwargs[self.object_id_field_name] = self.pk_val 
    274             obj = self.model(**kwargs) 
    275             obj.save() 
    276             return obj 
     274            return super(GenericRelatedObjectManager, self).create(**kwargs) 
    277275        create.alters_data = True 
    278276 
  • django/trunk/django/db/models/fields/related.py

    r8823 r8884  
    307307 
    308308            def create(self, **kwargs): 
    309                 new_obj = self.model(**kwargs) 
    310                 self.add(new_obj) 
    311                 return new_obj 
     309                kwargs.update({rel_field.name: instance}) 
     310                return super(RelatedManager, self).create(**kwargs) 
    312311            create.alters_data = True 
    313312 
     
    411410            if through is not None: 
    412411                raise AttributeError, "Cannot use create() on a ManyToManyField which specifies an intermediary model. Use %s's Manager instead." % through 
    413             new_obj = self.model(**kwargs) 
    414             new_obj.save() 
     412            new_obj = super(ManyRelatedManager, self).create(**kwargs) 
    415413            self.add(new_obj) 
    416414            return new_obj 
  • django/trunk/tests/modeltests/custom_pk/models.py

    r7322 r8884  
    77""" 
    88 
    9 from django.db import models 
     9from django.conf import settings 
     10from django.db import models, transaction, IntegrityError 
    1011 
    1112class Employee(models.Model): 
    12     employee_code = models.CharField(max_length=10, primary_key=True, 
    13             db_column = 'code') 
     13    employee_code = models.IntegerField(primary_key=True, db_column = 'code') 
    1414    first_name = models.CharField(max_length=20) 
    1515    last_name = models.CharField(max_length=20) 
     
    3030 
    3131__test__ = {'API_TESTS':""" 
    32 >>> dan = Employee(employee_code='ABC123', first_name='Dan', last_name='Jones') 
     32>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones') 
    3333>>> dan.save() 
    3434>>> Employee.objects.all() 
    3535[<Employee: Dan Jones>] 
    3636 
    37 >>> fran = Employee(employee_code='XYZ456', first_name='Fran', last_name='Bones') 
     37>>> fran = Employee(employee_code=456, first_name='Fran', last_name='Bones') 
    3838>>> fran.save() 
    3939>>> Employee.objects.all() 
    4040[<Employee: Fran Bones>, <Employee: Dan Jones>] 
    4141 
    42 >>> Employee.objects.get(pk='ABC123'
     42>>> Employee.objects.get(pk=123
    4343<Employee: Dan Jones> 
    44 >>> Employee.objects.get(pk='XYZ456'
     44>>> Employee.objects.get(pk=456
    4545<Employee: Fran Bones> 
    46 >>> Employee.objects.get(pk='foo'
     46>>> Employee.objects.get(pk=42
    4747Traceback (most recent call last): 
    4848    ... 
     
    5050 
    5151# Use the name of the primary key, rather than pk. 
    52 >>> Employee.objects.get(employee_code__exact='ABC123'
     52>>> Employee.objects.get(employee_code__exact=123
    5353<Employee: Dan Jones> 
    5454 
    5555# pk can be used as a substitute for the primary key. 
    56 >>> Employee.objects.filter(pk__in=['ABC123','XYZ456']) 
     56>>> Employee.objects.filter(pk__in=[123, 456]) 
    5757[<Employee: Fran Bones>, <Employee: Dan Jones>] 
    5858 
    5959# The primary key can be accessed via the pk property on the model. 
    60 >>> e = Employee.objects.get(pk='ABC123'
     60>>> e = Employee.objects.get(pk=123
    6161>>> e.pk 
    62 u'ABC123' 
     62123 
    6363 
    6464# Or we can use the real attribute name for the primary key: 
    6565>>> e.employee_code 
    66 u'ABC123' 
     66123 
    6767 
    6868# Fran got married and changed her last name. 
    69 >>> fran = Employee.objects.get(pk='XYZ456'
     69>>> fran = Employee.objects.get(pk=456
    7070>>> fran.last_name = 'Jones' 
    7171>>> fran.save() 
    7272>>> Employee.objects.filter(last_name__exact='Jones') 
    7373[<Employee: Dan Jones>, <Employee: Fran Jones>] 
    74 >>> emps = Employee.objects.in_bulk(['ABC123', 'XYZ456']) 
    75 >>> emps['ABC123'
     74>>> emps = Employee.objects.in_bulk([123, 456]) 
     75>>> emps[123
    7676<Employee: Dan Jones> 
    7777 
     
    9797[<Employee: Dan Jones>, <Employee: Fran Jones>] 
    9898 
    99 >>> Business.objects.filter(employees__employee_code__exact='ABC123'
     99>>> Business.objects.filter(employees__employee_code__exact=123
    100100[<Business: Sears>] 
    101 >>> Business.objects.filter(employees__pk='ABC123'
     101>>> Business.objects.filter(employees__pk=123
    102102[<Business: Sears>] 
    103103>>> Business.objects.filter(employees__first_name__startswith='Fran') 
     
    105105 
    106106# Primary key may be unicode string 
    107 >>> emp = Employee(employee_code='jaźń') 
    108 >>> emp.save() 
     107>>> bus = Business(name=u'jaźń') 
     108>>> bus.save() 
     109 
     110# The primary key must also obviously be unique, so trying to create a new 
     111# object with the same primary key will fail. 
     112>>> try: 
     113...    sid = transaction.savepoint() 
     114...    Employee.objects.create(employee_code=123, first_name='Fred', last_name='Jones') 
     115...    transaction.savepoint_commit(sid) 
     116... except Exception, e: 
     117...    if isinstance(e, IntegrityError): 
     118...        transaction.savepoint_rollback(sid) 
     119...        print "Pass" 
     120...    else: 
     121...        print "Fail with %s" % type(e) 
     122Pass 
    109123 
    110124"""} 
     125 
     126# SQLite lets objects be saved with an empty primary key, even though an 
     127# integer is expected. So we can't check for an error being raised in that case 
     128# for SQLite. Remove it from the suite for this next bit. 
     129if settings.DATABASE_ENGINE != 'sqlite3': 
     130    __test__["API_TESTS"] += """ 
     131# The primary key must be specified, so an error is raised if you try to create 
     132# an object without it. 
     133>>> try: 
     134...     sid = transaction.savepoint() 
     135...     Employee.objects.create(first_name='Tom', last_name='Smith') 
     136...     print 'hello' 
     137...     transaction.savepoint_commit(sid) 
     138...     print 'hello2' 
     139... except Exception, e: 
     140...     if isinstance(e, IntegrityError): 
     141...         transaction.savepoint_rollback(sid) 
     142...         print "Pass" 
     143...     else: 
     144...         print "Fail with %s" % type(e) 
     145Pass 
     146 
     147""" 
  • django/trunk/tests/modeltests/get_or_create/models.py

    r8450 r8884  
    1616    def __unicode__(self): 
    1717        return u'%s %s' % (self.first_name, self.last_name) 
     18 
     19class ManualPrimaryKeyTest(models.Model): 
     20    id = models.IntegerField(primary_key=True) 
     21    data = models.CharField(max_length=100) 
    1822 
    1923__test__ = {'API_TESTS':""" 
     
    6266...         print "Fail with %s" % type(e) 
    6367Pass 
     68 
     69# If you specify an existing primary key, but different other fields, then you 
     70# will get an error and data will not be updated. 
     71>>> m = ManualPrimaryKeyTest(id=1, data='Original') 
     72>>> m.save() 
     73>>> try: 
     74...    m, created = ManualPrimaryKeyTest.objects.get_or_create(id=1, data='Different') 
     75... except Exception, e: 
     76...    if isinstance(e, IntegrityError): 
     77...        print "Pass" 
     78...    else: 
     79...        print "Fail with %s" % type(e) 
     80Pass 
     81>>> ManualPrimaryKeyTest.objects.get(id=1).data == 'Original' 
     82True 
    6483"""}