浏览代码

Custom image model guide (#354)

Vince Salvino 4 年之前
父节点
当前提交
21bcbc1847

+ 35 - 5
docs/_static/docs.css

@@ -240,25 +240,55 @@ div.footer {
     clear: both;
 }
 
-div.admonition {
+div.admonition,
+div.versionadded,
+div.versionchanged,
+div.deprecated {
     background-color: #fafcff;
-    border-color: #d0e0f0;
+    border: 1px solid #d0e0f0;
     border-radius: 4px;
     border-width: 1.5px;
     color: #248;
     padding: 1em;
+    margin: 1em 0;
 }
-div.admonition code {
+div.admonition code,
+div.versionadded code,
+div.versionchanged code,
+div.deprecated code {
     background-color: #edeff2;
 }
-div.admonition.warning {
+div.admonition.warning,
+div.versionchanged,
+div.deprecated {
     background-color:#fffcfa;
     border-color:#f0e0d0;
     color:#842;
 }
-div.admonition.warning code {
+div.admonition.warning code,
+div.versionchanged code,
+div.deprecated code {
     background-color: #f5e5d5;
 }
+div.admonition > :last-child,
+div.versionadded > :last-child,
+div.versionchanged > :last-child,
+div.deprecated > :last-child {
+    margin-bottom: 0;
+}
+div.admonition > :first-child,
+div.versionadded > :first-child,
+div.versionchanged > :first-child,
+div.deprecated > :first-child {
+    margin-top: 0;
+}
+p.admonition-title,
+span.versionmodified {
+    font-weight: 700;
+    font-style: normal;
+    margin: 0 0.5em 0 0;
+    display: inline;
+}
 
 div.figure img {
     box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);

+ 45 - 0
docs/how_to/_custom_image1.rst

@@ -0,0 +1,45 @@
+Step 1: Create a custom image model in a new app
+------------------------------------------------
+
+It is imperative that the custom image model lives in a Django app which does
+not rely on or import ``coderedcms``. It is recommended to create a separate
+"pure" app to contain custom image and document models for your site. Failure
+to separate the custom image model will create a circular dependency issue in
+migrations.
+
+Create an empty Django app, ours will be named ``mediamodels``:
+
+.. code-block:: console
+
+    $ django-admin startapp mediamodels
+
+In ``mediamodels/models.py``, add your custom image model code, following the
+`Wagtail custom image sample code <https://docs.wagtail.io/en/stable/advanced_topics/images/custom_image_model.html>`_:
+
+.. code-block:: python
+
+    # models.py
+
+    from django.db import models
+    from wagtail.images.models import Image, AbstractImage, AbstractRendition
+
+
+    class CustomImage(AbstractImage):
+        # Add any extra fields to image here
+
+        # eg. To add a caption field:
+        # caption = models.CharField(max_length=255, blank=True)
+
+        admin_form_fields = Image.admin_form_fields + (
+            # Then add the field names here to make them appear in the form:
+            # 'caption',
+        )
+
+
+    class CustomRendition(AbstractRendition):
+        image = models.ForeignKey(CustomImage, on_delete=models.CASCADE, related_name='renditions')
+
+        class Meta:
+            unique_together = (
+                ('image', 'filter_spec', 'focal_point_key'),
+            )

+ 10 - 0
docs/how_to/_custom_image2.rst

@@ -0,0 +1,10 @@
+Step 2: Make migrations
+-----------------------
+
+**Before** switching your project to the new custom model, first make a
+migration for this model. If your custom image model already exists and has
+already been migrated, you can skip this step.
+
+.. code-block:: console
+
+    $ python manage.py makemigrations mediamodels

+ 9 - 0
docs/how_to/_custom_image3.rst

@@ -0,0 +1,9 @@
+Step 3: Switch to the new image model
+-------------------------------------
+
+In your Django settings file, (probably under ``settings/base.py``) set the
+``WAGTAILIMAGES_IMAGE_MODEL`` setting to point to it:
+
+.. code-block:: python
+
+    WAGTAILIMAGES_IMAGE_MODEL = "mediamodels.CustomImage"

+ 82 - 0
docs/how_to/convert_image_model.rst

@@ -0,0 +1,82 @@
+Convert Existing Site to Use a Custom Image Model
+=================================================
+
+.. versionadded:: 0.19
+
+    Added support for custom image models. You must be on CodeRed CMS version
+    0.19 or higher in order to follow this guide.
+
+Using a custom image model is a very similar process to using a custom user
+model in Django --- it is easy to do when starting a new project but extremely
+difficult to do mid-project. This process requires deep understanding of the
+Django ORM, SQL, and relational database design. It is therefore recommended to
+truly evaluate if and why you really need to switch to a custom image model. If
+you're simply looking to store metadata about an image, the same effect could be
+much more easily achieved with a separate "metadata" model with a `OneToOne
+<https://docs.djangoproject.com/en/stable/topics/db/examples/one_to_one/>`_
+relationship to the Image model, and do a reverse lookup (e.g.
+``image.metadata``).
+
+Before starting this guide, ensure you have updated to the latest CodeRed CMS,
+have run all migrations, and do not have any pending migrations.
+
+.. code-block:: console
+
+    $ python manage.py migrate
+    $ python manage.py makemigrations
+    No changes detected
+
+
+.. include:: _custom_image1.rst
+
+.. include:: _custom_image2.rst
+
+Now, apply the migration:
+
+.. code-block:: console
+
+    $ python manage.py migrate mediamodels
+
+.. include:: _custom_image3.rst
+
+
+Step 4: Migrate your models and database schema by hand
+-------------------------------------------------------
+
+At this point the database tables of existing coderedcms models have FK pointing
+to ``wagtailimages.Image``, however Django thinks they are pointing to the new
+custom image table, hence creating FOREIGN KEY constraint problems.
+
+For this same reason, running ``makemigrations`` will yield "No changes
+detected" as the Django ORM has no knowledge that the foreign keys are pointing
+to the wrong tables. Hence the database schema must be changed by hand.
+
+The end result is your existing image database tables should be moved to the new
+custom image table, and every current table with a foreign key to the old image
+table needs to be updated as a foreign key to the new image table.
+
+This process will differ from project to project, so you will need to find your
+own way to update the database schema that fits your project. Many related
+discussions about switching the Django User model (replace "user" with "image"
+in this context) can be found online and are highly relevant and helpful. Start
+by reading `Django ticket #25313 <https://code.djangoproject.com/ticket/25313>`_
+on the subject.
+
+To help with your database update, below is a list of each concrete CodeRed
+model which references the Image. A `search query of the source code
+<https://github.com/coderedcorp/coderedcms/search?l=Python&q=get_image_model_string>`_
+can also yield specific results.
+
+* ``coderedcms.models.CoderedPage.cover_image``
+
+* ``coderedcms.models.CoderedPage.og_image``
+
+* ``coderedcms.models.CoderedPage.struct_org_logo``
+
+* ``coderedcms.models.CoderedPage.struct_org_image``
+
+* ``coderedcms.models.CarouselSlide.image``
+
+* ``coderedcms.models.LayoutSettings.logo``
+
+* ``coderedcms.models.LayoutSettings.favicon``

+ 6 - 5
docs/how_to/docker.rst

@@ -14,7 +14,6 @@ For the sake of this guide, we will assume your Django project is named
 .. _install Docker: https://docs.Docker.com/engine/install/
 
 
-
 Step 1: Choose How to Use Docker
 --------------------------------
 
@@ -25,7 +24,6 @@ The most common way of working with Docker is to create a static Docker image,
 containing all of your code, which is effectively versioned in tandem with your
 git repository. Each time you change your project code, you also create a new
 version of the image. Because this image is effectively static and mirrors
-
 version control, there is no way to store dynamic files such as a database or
 media files. In this setup, you would want to use 3rd party services such as AWS
 S3 for files, or AWS RDS for database. Nearly all cloud platforms provide
@@ -125,9 +123,8 @@ extension). Copy the contents below into the file:
     CMD exec waitress serve --listen "*:8000" "myproject.wsgi:application"
 
 
-Step 2: Build and Run Your Image
---------------------------------
-
+Step 2: Build Your Image
+------------------------
 
 Next, with Docker running on your machine, create an image by running the
 following from your command line, replacing ``/path/to/Dockerfile`` and
@@ -146,6 +143,10 @@ essentially like version control, as such many people choose to use their
 current git commit ID as the tag. If you are using the "Image as Environment"
 approach, then this tag would likely be your Python version, e.g. ``py3.8.1``
 
+
+Step 3: Run a Container Using the Image
+---------------------------------------
+
 Now, create a container using the image. If using the "Versioned Image"
 approach:
 

+ 2 - 0
docs/how_to/index.rst

@@ -12,3 +12,5 @@ with CodeRed CMS.
     link_targets
     translation
     docker
+    use_custom_image_model
+    convert_image_model

+ 34 - 0
docs/how_to/use_custom_image_model.rst

@@ -0,0 +1,34 @@
+Using a Custom Image Model in CodeRed CMS
+=========================================
+
+.. versionadded:: 0.19
+
+    Added support for custom image models. You must be on CodeRed CMS version
+    0.19 or higher in order to follow this guide.
+
+Using a custom image model is a very similar process to using a custom user
+model in Django --- it is easy to do when starting a new project but extremely
+difficult to do mid-project. This guide will cover starting a **new** project
+using a custom image model. To switch to a custom image model mid-project,
+see :doc:`convert_image_model`.
+
+Before starting this guide, it is important that you are starting with a fresh
+empty database and have **never run coderedcms migrations!**
+
+
+.. include:: _custom_image1.rst
+
+.. include:: _custom_image2.rst
+
+.. include:: _custom_image3.rst
+
+
+Step 4: Migrate CodeRed CMS
+---------------------------
+
+Now you may run **all** migrations which will properly wire everything up to
+use your custom image model.
+
+.. code-block:: console
+
+    $ python manage.py migrate

+ 14 - 2
docs/releases/v0.19.0.rst

@@ -31,13 +31,25 @@ New features
   been simplified. See upgrade considerations below if you'd like to simplify
   your ``.scss`` files created from an older version of CodeRed CMS.
 
-* New guide: :doc:`/how_to/headers_and_footers`
-
 * As of 0.19, we will no longer maintain separate versions of docs for each
   release. The single stable docs will contain notes for each feature if that
   feature is changed, added, or removed in a particular release.
 
 
+Documentation
+-------------
+
+See the following new guides!
+
+* :doc:`/how_to/headers_and_footers`
+
+* :doc:`/how_to/docker`
+
+* :doc:`/how_to/use_custom_image_model`
+
+* :doc:`/how_to/convert_image_model`
+
+
 Upgrade considerations
 ----------------------