Ticket #8318: 8318.diff

File 8318.diff, 1.9 KB (added by Fred Bartle, 10 years ago)

override get_or_create() in ManyRelatedManager

  • django/db/models/fields/related.py

     
    409409            return new_obj
    410410        create.alters_data = True
    411411
     412        def get_or_create(self, **kwargs):
     413            # This check needs to be done here, since we can't later remove this
     414            # from the method lookup table, as we do with add and remove.
     415            if through is not None:
     416                raise AttributeError, "Cannot use get_or_create() on a ManyToManyField which specifies an intermediary model. Use %s's Manager instead." % through
     417            assert kwargs, \
     418                    'get_or_create() must be passed at least one keywoard argument'
     419            defaults = kwargs.pop('defaults', {})
     420            try:
     421                obj = self.get(**kwargs)
     422            except self.model.DoesNotExist:
     423                try:
     424                    params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
     425                    params.update(defaults)
     426                    obj = self.model(**params)
     427                    sid = transaction.savepoint()
     428                    obj.save()
     429                    transaction.savepoint_commit(sid)
     430                except IntegrityError, e:
     431                    tranasction.savepoint_rollback(sid)
     432                    obj = self.get(**kwargs)
     433                    self.add(obj)
     434                    return obj, False
     435                else:
     436                    self.add(obj)
     437                    return obj, True
     438            else:
     439                self.add(obj)
     440                return obj, False
     441        get_or_create.alters_data = True
     442
    412443        def _add_items(self, source_col_name, target_col_name, *objs):
    413444            # join_table: name of the m2m link table
    414445            # source_col_name: the PK colname in join_table for the source object
Back to Top