diff --git a/curriculum/migrations/0020_auto_20200509_2123.py b/curriculum/migrations/0020_auto_20200509_2123.py new file mode 100644 index 0000000..e79168a --- /dev/null +++ b/curriculum/migrations/0020_auto_20200509_2123.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.5 on 2020-05-09 21:23 + +from django.db import migrations +from sortedm2m.operations import AlterSortedManyToManyField +from sortedm2m import fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('curriculum', '0019_auto_20200426_1822'), + ] + + operations = [ + AlterSortedManyToManyField( + model_name='lessonplan', + name='materials', + field=fields.SortedManyToManyField(blank=True, help_text=None, to='curriculum.Material'), + ), + ] diff --git a/curriculum/models.py b/curriculum/models.py index f770b04..14a7009 100644 --- a/curriculum/models.py +++ b/curriculum/models.py @@ -4,6 +4,8 @@ from django.shortcuts import reverse from django.utils.text import slugify +from sortedm2m.fields import SortedManyToManyField + from accounts.models import GRADE_LEVEL_MAX_LENGTH, GradeLevels @@ -94,7 +96,7 @@ class LessonPlan(models.Model): resources = models.ManyToManyField(LessonResource, blank=True) resource_links = models.ManyToManyField(LessonResourceExternalLink, blank=True) - materials = models.ManyToManyField(Material, blank=True) + materials = SortedManyToManyField(Material, blank=True) # enable feedback? feedback_enabled = models.BooleanField(default=True) diff --git a/firstbyte/settings.py b/firstbyte/settings.py index b6f66a6..e2be021 100644 --- a/firstbyte/settings.py +++ b/firstbyte/settings.py @@ -67,6 +67,7 @@ 'rest_framework', 'crispy_forms', 'storages', + 'sortedm2m', 'django.contrib.humanize', 'django.contrib.admin', 'django.contrib.auth', diff --git a/poetry.lock b/poetry.lock index 07d8e10..e164e0f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -140,6 +140,14 @@ pytz = ">=2016.10" [package.extras] bounce = ["requests (<3)", "m2crypto"] +[[package]] +category = "main" +description = "Drop-in replacement for django's many to many field with sorted relations." +name = "django-sortedm2m" +optional = false +python-versions = "*" +version = "3.0.0" + [[package]] category = "main" description = "Support for many storage backends in Django" @@ -406,7 +414,7 @@ python-versions = "*" version = "1.12.1" [metadata] -content-hash = "bea206125ffd5dcbe2666c4fecc66834e7b304bc616ee30b1038840e22541345" +content-hash = "16da08dd6ae0c86dd73c0c4583729b567780a2c7c57220848a69575a2cc22b85" python-versions = "3.8.2" [metadata.files] @@ -461,6 +469,9 @@ django-ses = [ {file = "django-ses-0.8.14.tar.gz", hash = "sha256:ad45fca653db1725d2237d5aa1a4e2705789088717d69b9a91e4a1c7688896b5"}, {file = "django_ses-0.8.14-py2.py3-none-any.whl", hash = "sha256:0077b9a70a0e1a8c4eb13c55451663fbca3b0bb14f462ed73eeb56aa330ab1ce"}, ] +django-sortedm2m = [ + {file = "django_sortedm2m-3.0.0-py2.py3-none-any.whl", hash = "sha256:363846516d26b193ef9b960c8031daf919795257359267814f029fb4d07ab5ce"}, +] django-storages = [ {file = "django-storages-1.9.1.tar.gz", hash = "sha256:a59e9923cbce7068792f75344ed7727021ee4ac20f227cf17297d0d03d141e91"}, {file = "django_storages-1.9.1-py2.py3-none-any.whl", hash = "sha256:3103991c2ee8cef8a2ff096709973ffe7106183d211a79f22cf855f33533d924"}, diff --git a/pyproject.toml b/pyproject.toml index 19c7d2b..cda6500 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ psycopg2 = "^2.8.5" django-ses = "^0.8.14" django-allauth = "^0.41.0" djangorestframework-camel-case = "^1.1.2" +django-sortedm2m = "^3.0.0" [tool.poetry.dev-dependencies] pylint = "^2.4.4" diff --git a/requirements.txt b/requirements.txt index 51f299e..8f6af2f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,65 +1,95 @@ -astroid==2.2.5 -awsebcli==3.15.2 -blessed==1.15.0 -boto==2.49.0 -boto3==1.9.86 -botocore==1.12.86 -cached-property==1.5.1 -cement==2.8.2 -certifi==2018.11.29 -chardet==3.0.4 -colorama==0.3.9 -defusedxml==0.5.0 -dj-database-url==0.5.0 -Django==2.2.10 -django-allauth==0.38.0 -django-crispy-forms==1.7.2 -django-heroku==0.3.1 -django-ses==0.8.9 -django-storages==1.7.1 -django-webpack-loader==0.6.0 -djangorestframework==3.11.0 -docker==3.7.0 -docker-compose==1.23.2 -docker-pycreds==0.4.0 -dockerpty==0.4.1 -docopt==0.6.2 -docutils==0.14 -EB==0.1.5 -ebcli==4.0.18 -enum34==1.1.6 -future==0.16.0 -gunicorn==20.0.4 -idna==2.7 -inflect==2.1.0 -isort==4.3.4 -Jinja2==2.10.3 -jmespath==0.9.3 -jsonschema==2.6.0 -keyring==9.0 -keyrings.alt==3.4.0 -lazy-object-proxy==1.3.1 -MarkupSafe==1.1.1 -mccabe==0.6.1 -oauthlib==3.0.0 -pathspec==0.5.9 -psycopg2==2.8.4 -psycopg2-binary==2.7.7 -python-dateutil==2.7.5 -python3-openid==3.1.0 -pytz==2018.9 -PyYAML==5.1.2 -requests==2.20.1 -requests-oauthlib==1.2.0 -s3transfer==0.1.13 -semantic-version==2.5.0 -six==1.11.0 -sqlparse==0.3.0 -termcolor==1.1.0 -texttable==0.9.1 -typed-ast==1.3.5 -urllib3==1.24.3 -wcwidth==0.1.7 -websocket-client==0.54.0 -whitenoise==5.0.1 -wrapt==1.11.1 +asgiref==3.2.7 \ + --hash=sha256:9ca8b952a0a9afa61d30aa6d3d9b570bb3fd6bafcf7ec9e6bed43b936133db1c \ + --hash=sha256:8036f90603c54e93521e5777b2b9a39ba1bad05773fcf2d208f0299d1df58ce5 +boto==2.49.0 \ + --hash=sha256:147758d41ae7240dc989f0039f27da8ca0d53734be0eb869ef16e3adcfa462e8 \ + --hash=sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a +certifi==2020.4.5.1 \ + --hash=sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304 \ + --hash=sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519 +chardet==3.0.4 \ + --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \ + --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae +defusedxml==0.6.0 \ + --hash=sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93 \ + --hash=sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5 +dj-database-url==0.5.0 \ + --hash=sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163 \ + --hash=sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9 +django==3.0.5 \ + --hash=sha256:642d8eceab321ca743ae71e0f985ff8fdca59f07aab3a9fb362c617d23e33a76 \ + --hash=sha256:d4666c2edefa38c5ede0ec1655424c56dc47ceb04b6d8d62a7eac09db89545c1 +django-allauth==0.41.0 \ + --hash=sha256:7ab91485b80d231da191d5c7999ba93170ef1bf14ab6487d886598a1ad03e1d8 +django-crispy-forms==1.9.0 \ + --hash=sha256:67e73ac863d3159500029fbbcdcb788f287a3fd357becebc1a0b51f73896dce3 \ + --hash=sha256:50032184708ce351e3c9f0008ac35d659d9d5973fa2db218066f2e0a76eb41d9 +django-heroku==0.3.1 \ + --hash=sha256:6af4bc3ae4a9b55eaad6dbe5164918982d2762661aebc9f83d9fa49f6009514e \ + --hash=sha256:2bc690aab89eedbe01311752320a9a12e7548e3b0ed102681acc5736a41a4762 +django-ses==0.8.14 \ + --hash=sha256:ad45fca653db1725d2237d5aa1a4e2705789088717d69b9a91e4a1c7688896b5 \ + --hash=sha256:0077b9a70a0e1a8c4eb13c55451663fbca3b0bb14f462ed73eeb56aa330ab1ce +django-sortedm2m==3.0.0 \ + --hash=sha256:363846516d26b193ef9b960c8031daf919795257359267814f029fb4d07ab5ce +django-storages==1.9.1 \ + --hash=sha256:a59e9923cbce7068792f75344ed7727021ee4ac20f227cf17297d0d03d141e91 \ + --hash=sha256:3103991c2ee8cef8a2ff096709973ffe7106183d211a79f22cf855f33533d924 +django-webpack-loader==0.7.0 \ + --hash=sha256:7a3c88201aa54481f9399465615cbe7b9aece8081496a6d0287b7cb8e232f447 \ + --hash=sha256:d28a276ed3d89e97a313b74967e373693f8b86afe629f4c91eea91c5b4f2ec20 +djangorestframework==3.11.0 \ + --hash=sha256:05809fc66e1c997fd9a32ea5730d9f4ba28b109b9da71fccfa5ff241201fd0a4 \ + --hash=sha256:e782087823c47a26826ee5b6fa0c542968219263fb3976ec3c31edab23a4001f +djangorestframework-camel-case==1.1.2 \ + --hash=sha256:9eba4a2f959e1e46b7d0f6136baf950552b2a4a695d4bb3cfb0c37be25294574 +future==0.18.2 \ + --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d +gunicorn==20.0.4 \ + --hash=sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c \ + --hash=sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626 +idna==2.9 \ + --hash=sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa \ + --hash=sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb +inflect==4.1.0 \ + --hash=sha256:053dabafaebc41375361cea2cbaea52f91c7d5bd30e079847ee4e4e49739d41b \ + --hash=sha256:def6f3791be9181f0c01e0bf5949304007ec6e04c6674fbef7cc49c657b8a9a5 +oauthlib==3.1.0 \ + --hash=sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea \ + --hash=sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889 +psycopg2==2.8.5 \ + --hash=sha256:a0984ff49e176062fcdc8a5a2a670c9bb1704a2f69548bce8f8a7bad41c661bf \ + --hash=sha256:acf56d564e443e3dea152efe972b1434058244298a94348fc518d6dd6a9fb0bb \ + --hash=sha256:440a3ea2c955e89321a138eb7582aa1d22fe286c7d65e26a2c5411af0a88ae72 \ + --hash=sha256:6b306dae53ec7f4f67a10942cf8ac85de930ea90e9903e2df4001f69b7833f7e \ + --hash=sha256:d3b29d717d39d3580efd760a9a46a7418408acebbb784717c90d708c9ed5f055 \ + --hash=sha256:6a471d4d2a6f14c97a882e8d3124869bc623f3df6177eefe02994ea41fd45b52 \ + --hash=sha256:27c633f2d5db0fc27b51f1b08f410715b59fa3802987aec91aeb8f562724e95c \ + --hash=sha256:2df2bf1b87305bd95eb3ac666ee1f00a9c83d10927b8144e8e39644218f4cf81 \ + --hash=sha256:ac5b23d0199c012ad91ed1bbb971b7666da651c6371529b1be8cbe2a7bf3c3a9 \ + --hash=sha256:2c0afb40cfb4d53487ee2ebe128649028c9a78d2476d14a67781e45dc287f080 \ + --hash=sha256:2327bf42c1744a434ed8ed0bbaa9168cac7ee5a22a9001f6fc85c33b8a4a14b7 \ + --hash=sha256:132efc7ee46a763e68a815f4d26223d9c679953cd190f1f218187cb60decf535 \ + --hash=sha256:f7d46240f7a1ae1dd95aab38bd74f7428d46531f69219954266d669da60c0818 +python3-openid==3.1.0 \ + --hash=sha256:628d365d687e12da12d02c6691170f4451db28d6d68d050007e4a40065868502 \ + --hash=sha256:0086da6b6ef3161cfe50fb1ee5cceaf2cda1700019fda03c2c5c440ca6abe4fa +pytz==2020.1 \ + --hash=sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed \ + --hash=sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048 +requests==2.23.0 \ + --hash=sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee \ + --hash=sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6 +requests-oauthlib==1.3.0 \ + --hash=sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a \ + --hash=sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d \ + --hash=sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc +sqlparse==0.3.1 \ + --hash=sha256:022fb9c87b524d1f7862b3037e541f68597a730a8843245c349fc93e1643dc4e \ + --hash=sha256:e162203737712307dfe78860cc56c8da8a852ab2ee33750e33aeadf38d12c548 +urllib3==1.25.9 \ + --hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115 \ + --hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 +whitenoise==5.0.1 \ + --hash=sha256:62556265ec1011bd87113fb81b7516f52688887b7a010ee899ff1fd18fd22700 \ + --hash=sha256:0f9137f74bd95fa54329ace88d8dc695fbe895369a632e35f7a136e003e41d73