Ticket #3688: recursive-related-fields-4692v2.diff
File recursive-related-fields-4692v2.diff, 6.5 KB (added by , 18 years ago) |
---|
-
django/db/models/fields/related.py
6 6 from django.utils.translation import gettext_lazy, string_concat, ngettext 7 7 from django.utils.functional import curry 8 8 from django.core import validators 9 from django.core.exceptions import ImproperlyConfigured 9 10 from django import oldforms 10 11 from django import newforms as forms 11 12 from django.dispatch import dispatcher … … 23 24 24 25 def add_lookup(rel_cls, field): 25 26 name = field.rel.to 26 module = rel_cls.__module__ 27 key = (module, name) 27 # name should be either the name of a model in the same application or the 28 # name of a model in another application referenced with standard Django 29 # dotted notation ('appname.modelname') 30 if name.find('.') is -1: 31 app_name = rel_cls._meta.app_label 32 model_name = name 33 else: 34 try: 35 app_name, model_name = name.split('.') 36 except ValueError: 37 raise ImproperlyConfigured, "Invalid definition for field %s (%s). Please use app_name.model_name notation." % (field.name, name) 38 key = (app_name, model_name) 28 39 # Has the model already been loaded? 29 40 # If so, resolve the string reference right away 30 model = get_model( rel_cls._meta.app_label, field.rel.to, False)41 model = get_model(app_name, model_name, False) 31 42 if model: 32 43 field.rel.to = model 33 44 field.do_related_class(model, rel_cls) … … 37 48 38 49 def do_pending_lookups(sender): 39 50 other_cls = sender 40 key = (other_cls._ _module__, other_cls.__name__)51 key = (other_cls._meta.app_label, other_cls.__name__) 41 52 for rel_cls, field in pending_lookups.setdefault(key, []): 42 53 field.rel.to = other_cls 43 54 field.do_related_class(other_cls, rel_cls) -
docs/model-api.txt
682 682 manufacturer = models.ForeignKey(Manufacturer) 683 683 # ... 684 684 685 To create a recursive relationship -- an object that has a many-to-one 686 relationship with itself -- use ``models.ForeignKey('self')``.685 For information on establishing relationships to ``self``, and as-of-yet 686 undefined models, see `recursive relationships`_ below. 687 687 688 If you need to create a relationship on a model that has not yet been defined,689 you can use the name of the model, rather than the model object itself::690 691 class Car(models.Model):692 manufacturer = models.ForeignKey('Manufacturer')693 # ...694 695 class Manufacturer(models.Model):696 # ...697 698 Note, however, that you can only use strings to refer to models in the same699 models.py file -- you cannot use a string to reference a model in a different700 application, or to reference a model that has been imported from elsewhere.701 702 688 Behind the scenes, Django appends ``"_id"`` to the field name to create its 703 689 database column name. In the above example, the database table for the ``Car`` 704 690 model will have a ``manufacturer_id`` column. (You can change this explicitly … … 817 803 # ... 818 804 toppings = models.ManyToManyField(Topping) 819 805 820 As with ``ForeignKey``, a relationship to self can be defined by using the 821 string ``'self'`` instead of the model name, and you can refer to as-yet 822 undefined models by using a string containing the model name. However, you 823 can only use strings to refer to models in the same models.py file -- you 824 cannot use a string to reference a model in a different application, or to 825 reference a model that has been imported from elsewhere. 826 806 For information on establishing relationships to ``self``, and as-of-yet 807 undefined models, see `recursive relationships`_ below. 808 827 809 It's suggested, but not required, that the name of a ``ManyToManyField`` 828 810 (``toppings`` in the example above) be a plural describing the set of related 829 811 model objects. … … 910 892 could make ``Restaurant`` have a ``OneToOneField`` to ``Place`` (because a 911 893 restaurant "is-a" place). 912 894 913 As with ``ForeignKey``, a relationship to self can be defined by using the 914 string ``"self"`` instead of the model name; references to as-yet undefined 915 models can be made by using a string containing the model name. 895 For information on establishing relationships to as-of-yet undefined models, 896 see `recursive relationships`_ below. 916 897 917 898 This ``OneToOneField`` will actually replace the primary key ``id`` field 918 899 (since one-to-one relations share the same primary key), and will be displayed … … 922 903 923 904 .. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/ 924 905 906 Recursive relationships 907 ~~~~~~~~~~~~~~~~~~~~~~~ 908 To create a recursive relationship -- an object that has a many-to-one 909 relationship with itself -- use ``models.ForeignKey('self')`` or 910 ``models.ManyToMany('self')`` 911 912 If you need to create a relationship on a model that has not yet been defined, 913 you can use the name of the model, rather than the model object itself:: 914 915 class Car(models.Model): 916 manufacturer = models.ForeignKey('Manufacturer') 917 # ... 918 919 class Manufacturer(models.Model): 920 # ... 921 922 Note, however, that you can only use strings to refer to models in the same 923 models.py file -- you cannot use a string to reference a model in a different 924 application, or to reference a model that has been imported from elsewhere. 925 926 **New in Django development version:** String-based references have been 927 expanded to allow reference to models in other models.py files. This usage 928 provides a mechanism for enabling recursive relationships between 929 tightly-coupled objects that logically reside in different applications. 930 931 For example, consider a user class and a series of articles:: 932 933 class User(models.Model): 934 saved_articles = models.ManyToManyField('Article') 935 # ... 936 937 class Article(models.Model): 938 author = models.ForeignKey(User) 939 # ... 940 941 It doesn't make much sense for users and articles to be stored in the same 942 models.py file. By using dotted-notation (``app_name.model_name``), it is 943 possible to reference across models.py files when recursive ``import`` 944 statements would otherwise cause problems. 945 946 my_project/accounts/models.py:: 947 948 class User(models.Model): 949 saved_articles = models.ManyToManyField('articles.Article') 950 # ... 951 952 my_project/articles/models.py:: 953 954 class Article(models.Model): 955 author = models.ForeignKey('accounts.User') 956 # ... 957 925 958 Meta options 926 959 ============ 927 960