Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#14944 closed (invalid)

Saving a model which refers to unexistent models does not spit any errors

Reported by: ferran Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I had these models:

class IPv4(models.Model):
    addr = models.IPAddressField(
        unique=True,
        primary_key=True
    )
    
    def __unicode__(self):
        return self.addr

class Hostname(models.Model):
    host = models.CharField(
        max_length=200,
        unique=True,
        primary_key=True,
    )
    
    def __unicode__(self):
        return self.host

class NameServer(models.Model):
    host = models.ForeignKey(Hostname, related_name="hostname")
    ip = models.ForeignKey(IPv4, related_name="ip address")
    handle = GenericRelation(Handle, null=True)
    
    def __unicode__(self):
        return "%s (%s)" % (self.host, self.ip)

    class Meta:
        unique_together = ('host', 'ip')

If i try to add a NameServer with non-saved models, it does not fail until it searches for objects:

>>> ns = NameServer(host=Hostname(host='tetuan.fompi.net'), ip=IPv4(addr='87.216.178.18'))
>>> ns.save()
>>> Hostname.objects.all()
[<Hostname: seie.fompi.net>, <Hostname: uno.uno.uno>, <Hostname: dos.dos.dos>]
>>> j.objects.all()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/django/db/models/manager.py", line 211, in __get__
    raise AttributeError("Manager isn't accessible via %s instances" % type.__name__)
AttributeError: Manager isn't accessible via NameServer instances
>>> NameServer.objects.all()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 71, in __repr__
    return repr(data)
  File "/usr/lib/python2.7/site-packages/django/db/models/base.py", line 344, in __repr__
    u = unicode(self)
  File "domains/models.py", line 114, in __unicode__
    return "%s (%s)" % (self.host, self.ip)
  File "/usr/lib/python2.7/site-packages/django/db/models/fields/related.py", line 302, in __get__
    rel_obj = QuerySet(self.field.rel.to).using(db).get(**params)
  File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 341, in get
    % self.model._meta.object_name)
DoesNotExist: Hostname matching query does not exist.

Change History (3)

comment:1 by ferran, 13 years ago

I think the wanted functionality is to do a cascade save() if referenced model does not have a pk value, i can't imagine a case scenario where might be useful to save a model referencing unexistent ones.

comment:2 by Honza Král, 13 years ago

Resolution: invalid
Status: newclosed

The ORM doesn't do any validation by default, you have to do that manually if you need it, see the docs for model validation for more details. Normally the DB will complain of violating a constraint, you must be using some DB that doesn't do that or have the table definitions in different state than reflected by your models.py.

btw. your unique_together won't work like this, it must be a tuple of tuples to work.

comment:3 by ferran, 13 years ago

Thank you, Honza_Kral; it seems like a South problem, i've just created a new app only with these model definitions and .save() method failed.

My fault for not testing it well.

Also, thank you for pointing out the unique_together issue; but it seems to work as is on django 1.0+

Note: See TracTickets for help on using tickets.
Back to Top