Opened 17 years ago

Closed 16 years ago

#4157 closed (wontfix)

Add is_equal method to models for other kinds of equality checking.

Reported by: Michael Axiak <axiak@…> Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: equality, models
Cc: Michael, Axiak, <axiak@…>, ferringb@… Triage Stage: Design decision needed
Has patch: yes Needs documentation: yes
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

There are many cases where one might want to check to see if two models are equal (and not just the same database row). If you take the OO analogy, you might want to see if two Articles are equivalent articles even if they are not the 'same' object.
This patch will allow one to do that. You can specify which fields you want to exclude by specifying attnames in the exclude parameter. If it's left unspecified, it will automatically exclude the primary key field(s). To disable excluding the primary key, just set excludes to [].
Examples:

class Article(models.Model):
    subject = models.CharField(maxlength=512)
    submitted = models.DateTimeField()
    author  = models.ForeignKey(User)

# suppose a and b only differ on when they were submitted

a = Article.objects.get(id = 5)
b = Article.objects.get(id = 6)

a.is_equal(b)
False

a.is_equal(a)
True

a.is_equal(b, ['id','submitted'])
True

a.is_equal(b, [])
False

a.is_equal(a, [])
True

Attachments (3)

5079-add_is_equal_to_model.diff (2.0 KB ) - added by Michael Axiak <axiak@…> 17 years ago.
The code to make it work.
5079-better_patch_for_is_equal_check.diff (2.0 KB ) - added by Michael Axiak <axiak@…> 17 years ago.
Cleaner Patch, now uses new Meta equality_exclude parameter
5079-better_patch_for_is_equal_check_2.diff (1.9 KB ) - added by Michael Axiak <axiak@…> 17 years ago.
This works a little better.

Download all attachments as: .zip

Change History (8)

by Michael Axiak <axiak@…>, 17 years ago

The code to make it work.

comment:1 by Michael Axiak <axiak@…>, 17 years ago

Needs documentation: set
Needs tests: set
Triage Stage: UnreviewedDesign decision needed

Patch might need improvement, depends on what people think.

comment:2 by James Bennett, 17 years ago

Any chance of implementing this as the more Pythonic __eq__ or __cmp__?

by Michael Axiak <axiak@…>, 17 years ago

Cleaner Patch, now uses new Meta equality_exclude parameter

comment:3 by Michael Axiak <axiak@…>, 17 years ago

I submitted a new patch...no docs or tests yet (waiting on thumbs up from developers actually).
This new patch will allow one to specify the excluded fields in Meta, like so:

class Article(models.Model):
    subject = models.CharField(maxlength=512)
    submitted = models.DateTimeField()
    author  = models.ForeignKey(User)

    class Meta:
        equality_exclude = ('submitted','id')

# suppose a and b only differ on when they were submitted

a = Article.objects.get(id = 5)
b = Article.objects.get(id = 6)

a.is_equal(b)
True

a.is_equal(b, [])
False

a.is_equal(b, ['submitted'])
False # ids differ

As a response to ubernostrum, eq currently uses the pk field to determine which if they are equal. Now that it uses a Meta field, we could have it override eq and have the default Meta make it just compare pk.

I'm not sure either way, and there seemed to be strong opinions in either direction. What's *YOUR* take?

by Michael Axiak <axiak@…>, 17 years ago

This works a little better.

in reply to:  3 comment:4 by (removed), 17 years ago

Cc: Michael Axiak <axiak@…> ferringb@… added; Michael Axiak <axiak@…> removed

comment:5 by Luke Plant, 16 years ago

Resolution: wontfix
Status: newclosed

Some points:

  • The current implementation of is_equal() is not very flexible -- for instance, a 'fuzzy' match on certain attributes (e.g. case insensitive equality) might be useful.
  • Why not just override __eq__ ?


  • With ether is_equal or __eq__, this could be easily implemented as a mixin:
class IsEqualMixin(object):
    def is_equal(self, other):
        # whatever you want here

    def __eq__(self, other):
        # whatever

class YourModel(IsEqualMixin, models.Model):
    # whatever

For these reasons, closing as WONTFIX.

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