Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

how_to_customise_models.rst 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. =======================
  2. How to customise models
  3. =======================
  4. This How-to describes how to replace Oscar models with your own. This allows you
  5. to add fields and custom methods. It builds upon the steps described in
  6. :doc:`/topics/customisation`. Please read it first and ensure that you've:
  7. * Created a Python module with the the same app label
  8. * Added it as Django app to ``INSTALLED_APPS``
  9. * Added a :file:`models.py` and :file:`admin.py`
  10. Example
  11. -------
  12. Suppose you want to add a ``video_url`` field to the core product model. This means
  13. that you want your application to use a subclass of
  14. :class:`oscar.apps.catalogue.abstract_models.AbstractProduct` which has an additional field.
  15. The first step is to create a local version of the "catalogue" app. At a minimum, this
  16. involves creating :file:`catalogue/models.py` within your project and changing ``INSTALLED_APPS``
  17. to point to your local version rather than Oscar's.
  18. Next, you can modify the ``Product`` model through subclassing::
  19. # yourproject/catalogue/models.py
  20. from django.db import models
  21. from oscar.apps.catalogue.abstract_models import AbstractProduct
  22. class Product(AbstractProduct):
  23. video_url = models.URLField()
  24. from oscar.apps.catalogue.models import *
  25. Make sure to import the remaining Oscar models at the bottom of your file.
  26. .. tip::
  27. Using ``from ... import *`` is strange isn't it? Yes it is, but it needs to
  28. be done at the bottom of the module due to the way Django registers models.
  29. The order that model classes are imported makes a difference, with only the
  30. first one for a given class name being registered.
  31. The last thing you need to do now is make Django update the database schema and
  32. create a new column in the product table. We recommend using migrations
  33. for this (internally Oscar already does this) so all you need to do is create a
  34. new schema migration.
  35. It is possible to simply create a new catalogue migration (using ``./manage.py
  36. makemigrations catalogue``) but this isn't recommended as any
  37. dependencies between migrations will need to be applied manually (by adding a
  38. ``dependencies`` attribute to the migration class).
  39. The recommended way to handle migrations is to copy the ``migrations`` directory
  40. from ``oscar/apps/catalogue`` into your new ``catalogue`` app. Then you can
  41. create a new (additional) migration using the ``makemigrations``
  42. management command::
  43. ./manage.py makemigrations catalogue
  44. which will pick up any customisations to the product model.
  45. To apply the migration you just created, all you have to do is run
  46. ``./manage.py migrate catalogue`` and the new column is added to the product
  47. table in the database.
  48. Customising Products
  49. --------------------
  50. You should inherit from ``AbstractProduct`` as above to alter behaviour for all
  51. your products. Further subclassing is not recommended, because using methods
  52. and attributes of concrete subclasses of ``Product`` are not available unless
  53. you explicitly cast them onto that class. To model different classes of
  54. products, use ``ProductClass`` and ``ProductAttribute`` instead.
  55. Model customisations are not picked up
  56. --------------------------------------
  57. It's a common problem that you're trying to customise one of Oscar's models,
  58. but your new fields don't seem to get picked up. That is usually caused by
  59. Oscar's models being imported before your customised ones. Django's model
  60. registration disregards all further model declarations.
  61. In your overriding :file:`models.py`, ensure that you import Oscar's models *after*
  62. your custom ones have been defined. If that doesn't help, you have an import
  63. from ``oscar.apps.*.models`` somewhere that is being executed before your models
  64. are parsed. One trick for finding that import: put ``assert False`` in the relevant
  65. Oscar's :file:`models.py`, and the stack trace will show you the importing module.
  66. If other modules need to import your models, then import from your local module,
  67. not from Oscar directly.
  68. Customising dashboard forms
  69. ---------------------------
  70. For example, we have customised Product model and have added several fields.
  71. And we want to show it in the form for editing. You can customise dashboard
  72. forms by creating your own form that subclasses Oscar's dashboard form for
  73. any model. For example, you can customise the ``Product`` form in
  74. :file:`apps/dashboard/catalogue/forms.py` as follows::
  75. from oscar.apps.dashboard.catalogue import forms as base_forms
  76. class ProductForm(base_forms.ProductForm):
  77. class Meta(base_forms.ProductForm.Meta):
  78. fields = (
  79. 'title', 'upc', 'on_sale',
  80. 'short_description', 'description',
  81. 'out_of_stock', 'bestseller',
  82. 'is_new', 'is_discountable', 'structure',
  83. 'markdown', 'markdown_reason')
  84. Finally, make sure that you have overridden the dashboard app in your settings:
  85. replace ``'oscar.apps.dashboard.catalogue'`` with ``'apps.dashboard.catalogue'``
  86. in the ``INSTALLED_APPS`` setting.