#11265: ForeignKey/OneToOneField should support user-defined id attribute name
-----------------------------------------------------+----------------------
 Reporter:  dstora                                   |       Owner:  nobody    
   Status:  new                                      |   Milestone:            
Component:  Database layer (models, ORM)             |     Version:  1.0       
 Keywords:  foreign key ForeignKey OneToOneField id  |       Stage:  Unreviewed
Has_patch:  1                                        |  
-----------------------------------------------------+----------------------
 Currently, when defining a !ForeignKey/OneToOneField field XXX, Django
 automatically defines a XXX_id attribute to store the id value.[[BR]]
 However, it is sometimes desirable to decide of the name as XXX_id may not
 be the most appropriate.

 ----

 Let's take the following example:

 - I initially have a table "Payment" with a "ccy_code" field designating a
 3-letter currency code.
 My model definition looks like:
 {{{
     from django.db import model
     class Payment(models.Model):
         # ...
         ccy_code = models.CharField(max_length=3)

 }}}
 In my python code I refer to the currency code as follows:
 {{{
     p = Payment()
     #...
     print p.ccy_code

 }}}

 - Later, I decide to actually create a "Currency" table to hold some
 information about currencies.
 And I also decide to define a foreign key constraint from "Payment" to
 "Currency".
 My model now looks like:
 {{{
     from django.db import model
     class Currency(models.Model):
         ccy_code = models.CharField(max_length=3, primary_key=True)
         #...
     class Payment(models.Model):
         # ...
         ccy = models.ForeignKey(Currency, to_field="ccy_code",
 db_column="ccy_code")

 }}}
 The problem here is that my existing Python code is broken, because
 "ccy_code" is not defined anymore for "Payment".
 Django has instead define a "ccy_id" attribute.

 ----

 Based on the principle that defining things like foreign keys should only
 add functionality (and not remove any) it seems quite important to me that
 one can choose the id attribute name.[[BR]]
 [[BR]]
 This can be achieved by adding an optional keyword argument to
 !ForeignKey/OneToOneField constructors (here I decided to call it
 "id_attr_name").[[BR]]
 The implementation of this feature is pretty small and fully backward-
 compatible.[[BR]]
 Here is the SVN diff against trunk:
 {{{
 Index: related.py
 ===================================================================
 --- related.py  (revision 10924)
 +++ related.py  (working copy)
 @@ -660,6 +660,7 @@
  class ForeignKey(RelatedField, Field):
      empty_strings_allowed = False
      def __init__(self, to, to_field=None, rel_class=ManyToOneRel,
 **kwargs):
 +        self.__id_attr_name = kwargs.pop('id_attr_name', None)
          try:
              to_name = to._meta.object_name.lower()
          except AttributeError: # to._meta doesn't exist, so it must be
 RECURSIVE_RELATIONSHIP_CONSTANT
 @@ -679,7 +680,10 @@
          self.db_index = True

      def get_attname(self):
 -        return '%s_id' % self.name
 +        if self.__id_attr_name:
 +            return self.__id_attr_name
 +        else:
 +            return '%s_id' % self.name

      def get_validator_unique_lookup_type(self):
          return '%s__%s__exact' % (self.name,
 self.rel.get_related_field().name)

 }}}

 In my example, I could then define my model like:
 {{{
     from django.db import model
     class Currency(models.Model):
         ccy_code = models.CharField(max_length=3, primary_key=True)
         #...
     class Payment(models.Model):
         # ...
         ccy = models.ForeignKey(Currency, to_field="ccy_code",
 db_column="ccy_code", id_attr_name="ccy_code")

 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/11265>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to