Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add manufacture_data django command #369

Merged
merged 1 commit into from Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -11,6 +11,13 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.

[5.10.0] - 2024-01-02
---------------------

Added
~~~~~
* Added manufacture_data management command

[5.9.0] - 2023-11-27
--------------------

Expand Down
4 changes: 4 additions & 0 deletions README.rst
Expand Up @@ -30,6 +30,8 @@ This repository includes shared utilities for:

* `Security Utilities`_: Includes a middleware to add CSP response headers.

* `Data Generation`_: Management command for generating Django data based on model factories.

.. _Cache Utilities: edx_django_utils/cache/README.rst

.. _Django User and Group Utilities: edx_django_utils/user/README.rst
Expand All @@ -44,6 +46,8 @@ This repository includes shared utilities for:

.. _Security Utilities: edx_django_utils/security/README.rst

.. _Data Generation: edx_django_utils/data_generation/README.rst

Documentation
-------------

Expand Down
88 changes: 88 additions & 0 deletions edx_django_utils/data_generation/README.rst
@@ -0,0 +1,88 @@
Django Data Generation
######################


Setting up in new repository
============================
* Create management command `manufacture_data`
* Command class must inherit from `edx_django_utils.data_generation.management.commands.manufacture_data.Command` as BaseCommand
* Command class file must import model factory classes

Example from https://github.com/openedx/enterprise-catalog/pull/734

.. code-block:: python

from edx_django_utils.data_generation.management.commands.manufacture_data import Command as BaseCommand
from enterprise_catalog.apps.catalog.tests.factories import *
class Command(BaseCommand):
# No further code needed
rgraber marked this conversation as resolved.
Show resolved Hide resolved

Usage
=====

(Using https://github.com/openedx/edx-enterprise/blob/master/enterprise/models.py through Devstack as an example)

Generating Basic Model
----------------------
Upon invoking the command, supply a model param (--model) that is a complete path to a model that has a corresponding test factory:

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomer`

This will generate an enterprise customer record with place holder values according to the test factory

Customizing Model Values
------------------------
We can also provide customizations to the record being generated:
marlonkeating marked this conversation as resolved.
Show resolved Hide resolved

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomer --name "FRED"`

'EnterpriseCustomer' fields: {'name': 'FRED'}

We can supply parent model/subfactory customizations as well (using django ORM query syntax):

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomerCatalog --enterprise_customer__site__name "Fred" --enterprise_catalog_query__title "JOE SHMO" --title "who?"`

'EnterpriseCustomerCatalog' fields: {'title': 'who?'}
'EnterpriseCustomer' fields: {}
'Site' fields: {'name': 'Fred'}

'EnterpriseCatalogQuery' fields: {'title': 'JOE SHMO'}

Note the non subclass customization --title "who?" is applied to the specified model EnterpriseCustomerCatalog

Customizing Foreign Keys
------------------------
Say we want to supply an existing record as a FK to our object:

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomerUser --enterprise_customer 994599e6-3787-48ba-a2d1-42d1bdf6c46e`

'EnterpriseCustomerUser' fields: {}
'EnterpriseCustomer' PK: 994599e6-3787-48ba-a2d1-42d1bdf6c46e

or we can do something like:
`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomerUser --enterprise_customer__site 9 --enterprise_customer__name "joe"`

'EnterpriseCustomerUser' fields: {}
'EnterpriseCustomer' fields: {'name': 'joe'}
'Site' PK: 9

Unsupported Cases
-----------------
One limitation of this script is that it can only customize objects it generates, and cannot customize existing objects specfied with FK:

To illustrate:

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomerUser --enterprise_customer__site__name "fred" --enterprise_customer 994599e6-3787-48ba-a2d1-42d1bdf6c46e`

would yield
`CommandError: This script does not support customizing provided existing objects`

Error Cases
-----------

If you try and get something that doesn't exist:

`./manage.py lms manufacture_data --model enterprise.models.EnterpriseCustomerUser --enterprise_customer <invalid uuid>`

we'd get:
`CommandError: Provided FK value: <invalid uuid> does not exist on EnterpriseCustomer`
Empty file.
Empty file.
Empty file.