CVE-2022-2134: Allocation of Resources Without Limits or Throttling (CWE-770)
value: Allocation of Resources Without Limits or Throttling in GitHub repository inventree/inventree prior to 0.8.0.
CWE description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
CVSS v3 base score: 6.5
Published: 2022-06-20T15:15Z
Repository: https://github.com/inventree/inventree
Language: Python
Files changed: InvenTree/InvenTree/fields.py, InvenTree/InvenTree/settings.py, InvenTree/InvenTree/static/css/color-themes/dark-reader.css, InvenTree/InvenTree/static/css/inventree.css, InvenTree/InvenTree/urls.py, InvenTree/build/migrations/0008_auto_20200201_1247.py, InvenTree/build/migrations/0014_auto_20200425_1243.py, InvenTree/build/migrations/0035_alter_build_notes.py, InvenTree/build/models.py, InvenTree/company/migrations/0010_auto_20200201_1231.py, InvenTree/company/migrations/0032_auto_20210403_1837.py, InvenTree/company/migrations/0045_alter_company_notes.py, InvenTree/company/models.py, InvenTree/order/migrations/0015_auto_20200201_2346.py, InvenTree/order/migrations/0020_auto_20200420_0940.py, InvenTree/order/migrations/0044_auto_20210404_2016.py, InvenTree/order/migrations/0053_salesordershipment.py, InvenTree/order/migrations/0070_auto_20220620_0728.py, InvenTree/order/models.py, InvenTree/part/migrations/0026_auto_20200131_1022.py, InvenTree/part/migrations/0029_auto_20200223_0901.py, InvenTree/part/migrations/0048_auto_20200902_1404.py, InvenTree/part/migrations/0061_auto_20210103_2313.py, InvenTree/part/migrations/0079_alter_part_notes.py, InvenTree/part/models.py, InvenTree/part/test_api.py, InvenTree/stock/migrations/0018_auto_20200202_0103.py, InvenTree/stock/migrations/0020_auto_20200206_1213.py, InvenTree/stock/migrations/0034_auto_20200426_0602.py, InvenTree/stock/migrations/0077_alter_stockitem_notes.py, InvenTree/stock/models.py, requirements.txt
Commit date: 2022-06-20 22:20:04 +1000
Commit message: Remove reliance on django-markdownx (#3231)

* Remove reliance on django-markdownx

- We are now rendering notes on the client side using easymde
- No longer any need to utilize the markdownx integration
- Adds character limit for notes fields`

* Adjust legacy migrations - remove references to markdownx

* Fix bug for company notes field
Diff: diff --git a/InvenTree/InvenTree/fields.py b/InvenTree/InvenTree/fields.py
index 9f5d63312..d521d48cc 100644
--- a/InvenTree/InvenTree/fields.py
+++ b/InvenTree/InvenTree/fields.py
@@ -155,5 +155,21 @@ class RoundingDecimalField(models.DecimalField):
         }
 
         defaults.update(kwargs)
 
         return super().formfield(**kwargs)
+
+
+class InvenTreeNotesField(models.TextField):
+    """Custom implementation of a 'notes' field"""
+
+    # Maximum character limit for the various 'notes' fields
+    NOTES_MAX_LENGTH = 50000
+
+    def __init__(self, **kwargs):
+        """Configure default initial values for this field"""
+        kwargs['max_length'] = self.NOTES_MAX_LENGTH
+        kwargs['verbose_name'] = _('Notes')
+        kwargs['blank'] = True
+        kwargs['null'] = True
+
+        super().__init__(**kwargs)
diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py
index 9487de5e6..e50c8fcea 100644
--- a/InvenTree/InvenTree/settings.py
+++ b/InvenTree/InvenTree/settings.py
@@ -13,11 +13,10 @@ import logging
 import os
 import random
 import socket
 import string
 import sys
-from datetime import datetime
 
 import django.conf.locale
 from django.core.files.storage import default_storage
 from django.utils.translation import gettext_lazy as _
 
@@ -251,11 +250,10 @@ INSTALLED_APPS = [
     'corsheaders',                          # Cross-origin Resource Sharing for DRF
     'crispy_forms',                         # Improved form rendering
     'import_export',                        # Import / export tables to file
     'django_cleanup.apps.CleanupConfig',    # Automatically delete orphaned MEDIA files
     'mptt',                                 # Modified Preorder Tree Traversal
-    'markdownx',                            # Markdown editing
     'markdownify',                          # Markdown template rendering
     'django_admin_shell',                   # Python shell for the admin interface
     'djmoney',                              # django-money integration
     'djmoney.contrib.exchange',             # django-money exchange rates
     'error_report',                         # Error reporting in the admin interface
@@ -873,14 +871,10 @@ ACCOUNT_ADAPTER = 'InvenTree.forms.CustomAccountAdapter'
 
 # login settings
 REMOTE_LOGIN = get_setting('INVENTREE_REMOTE_LOGIN', CONFIG.get('remote_login', False))
 REMOTE_LOGIN_HEADER = get_setting('INVENTREE_REMOTE_LOGIN_HEADER', CONFIG.get('remote_login_header', 'REMOTE_USER'))
 
-# Markdownx configuration
-# Ref: https://neutronx.github.io/django-markdownx/customization/
-MARKDOWNX_MEDIA_PATH = datetime.now().strftime('markdownx/%Y/%m/%d')
-
 # Markdownify configuration
 # Ref: https://django-markdownify.readthedocs.io/en/latest/settings.html
 
 MARKDOWNIFY_WHITELIST_TAGS = [
     'a',
diff --git a/InvenTree/InvenTree/static/css/color-themes/dark-reader.css b/InvenTree/InvenTree/static/css/color-themes/dark-reader.css
index 9a383d4fd..ef44c7d06 100644
--- a/InvenTree/InvenTree/static/css/color-themes/dark-reader.css
+++ b/InvenTree/InvenTree/static/css/color-themes/dark-reader.css
@@ -3537,19 +3537,10 @@ a.ui-button:active,
     border-color: rgb(72, 78, 81);
 }
 .index-action-selected {
     background-color: rgb(32, 34, 36);
 }
-.markdownx .row {
-    border-color: rgb(31, 31, 92);
-}
-.markdownx-editor {
-    border-color: rgb(31, 31, 92);
-}
-.markdownx-preview {
-    border-color: rgb(31, 31, 92);
-}
 .progress {
     background-image: initial;
     background-color: rgb(32, 34, 36);
 }
 .progress-bar {
diff --git a/InvenTree/InvenTree/static/css/inventree.css b/InvenTree/InvenTree/static/css/inventree.css
index 018697823..96409dc9a 100644
--- a/InvenTree/InvenTree/static/css/inventree.css
+++ b/InvenTree/InvenTree/static/css/inventree.css
@@ -61,34 +61,14 @@ main {
 
 .index-action-selected {
     background-color: #EEEEF5;
 }
 
-.markdownx .row {
-    margin: 5px;
-    padding: 5px;
-    border: 1px solid #cce;
-    border-radius: 4px;
-}
-
-.markdownx-editor {
-    width: 100%;
-    border: 1px solid #cce;
-    border-radius: 3px;
-    padding: 10px;
-}
-
 .panel-content {
     padding: 10px;
 }
 
-.markdownx-preview {
-    border: 1px solid #cce;
-    border-radius: 3px;
-    padding: 10px;
-}
-
 /* Progress bars */
 
 .progress {
     position: relative;
     width: 100%;
diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py
index 54bd4dd88..2ccbe6d25 100644
--- a/InvenTree/InvenTree/urls.py
+++ b/InvenTree/InvenTree/urls.py
@@ -124,13 +124,10 @@ backendpatterns = [
     re_path(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
     re_path(r'^auth/?', auth_request),
 
     re_path(r'^api/', include(apipatterns)),
     re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')),
-
-    # 3rd party endpoints
-    re_path(r'^markdownx/', include('markdownx.urls')),
 ]
 
 frontendpatterns = [
 
     # Apps
diff --git a/InvenTree/build/migrations/0008_auto_20200201_1247.py b/InvenTree/build/migrations/0008_auto_20200201_1247.py
index 99e916cd3..ff311ee18 100644
--- a/InvenTree/build/migrations/0008_auto_20200201_1247.py
+++ b/InvenTree/build/migrations/0008_auto_20200201_1247.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-01 12:47
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='build',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes'),
+            field=models.TextField(blank=True, help_text='Extra build notes'),
         ),
     ]
diff --git a/InvenTree/build/migrations/0014_auto_20200425_1243.py b/InvenTree/build/migrations/0014_auto_20200425_1243.py
index c8148b6c1..af65a12cb 100644
--- a/InvenTree/build/migrations/0014_auto_20200425_1243.py
+++ b/InvenTree/build/migrations/0014_auto_20200425_1243.py
@@ -2,11 +2,10 @@
 
 import InvenTree.fields
 import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 import mptt.fields
 
 
 class Migration(migrations.Migration):
 
@@ -29,11 +28,11 @@ class Migration(migrations.Migration):
             field=InvenTree.fields.InvenTreeURLField(blank=True, help_text='Link to external URL', verbose_name='External Link'),
         ),
         migrations.AlterField(
             model_name='build',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
+            field=models.TextField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='build',
             name='parent',
             field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='build.Build', verbose_name='Parent Build'),
diff --git a/InvenTree/build/migrations/0035_alter_build_notes.py b/InvenTree/build/migrations/0035_alter_build_notes.py
new file mode 100644
index 000000000..a86570069
--- /dev/null
+++ b/InvenTree/build/migrations/0035_alter_build_notes.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.13 on 2022-06-20 07:28
+
+import InvenTree.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('build', '0034_alter_build_reference_int'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='build',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Extra build notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+    ]
diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py
index 3659ad4b5..9ed095869 100644
--- a/InvenTree/build/models.py
+++ b/InvenTree/build/models.py
@@ -14,12 +14,10 @@ from django.db.models.functions import Coalesce
 from django.db.models.signals import post_save
 from django.dispatch.dispatcher import receiver
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 
-from markdownx.models import MarkdownxField
-
 from mptt.models import MPTTModel, TreeForeignKey
 from mptt.exceptions import InvalidMove
 
 from rest_framework import serializers
 
@@ -318,13 +316,12 @@ class Build(MPTTModel, ReferenceIndexingMixin):
     link = InvenTree.fields.InvenTreeURLField(
         verbose_name=_('External Link'),
         blank=True, help_text=_('Link to external URL')
     )
 
-    notes = MarkdownxField(
-        verbose_name=_('Notes'),
-        blank=True, help_text=_('Extra build notes')
+    notes = InvenTree.fields.InvenTreeNotesField(
+        help_text=_('Extra build notes')
     )
 
     def sub_builds(self, cascade=True):
         """Return all Build Order objects under this one."""
         if cascade:
diff --git a/InvenTree/company/migrations/0010_auto_20200201_1231.py b/InvenTree/company/migrations/0010_auto_20200201_1231.py
index c5afeae2d..c3839f68d 100644
--- a/InvenTree/company/migrations/0010_auto_20200201_1231.py
+++ b/InvenTree/company/migrations/0010_auto_20200201_1231.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-01 12:31
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='company',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True),
+            field=models.TextField(blank=True),
         ),
     ]
diff --git a/InvenTree/company/migrations/0032_auto_20210403_1837.py b/InvenTree/company/migrations/0032_auto_20210403_1837.py
index 41b6977d3..d9c83d75e 100644
--- a/InvenTree/company/migrations/0032_auto_20210403_1837.py
+++ b/InvenTree/company/migrations/0032_auto_20210403_1837.py
@@ -3,11 +3,10 @@
 import InvenTree.fields
 import company.models
 import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 import stdimage.models
 
 
 class Migration(migrations.Migration):
 
@@ -42,11 +41,11 @@ class Migration(migrations.Migration):
             field=InvenTree.fields.InvenTreeURLField(blank=True, help_text='Link to external company information', verbose_name='Link'),
         ),
         migrations.AlterField(
             model_name='company',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, verbose_name='Notes'),
+            field=models.TextField(blank=True, verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='supplierpart',
             name='base_cost',
             field=models.DecimalField(decimal_places=3, default=0, help_text='Minimum charge (e.g. stocking fee)', max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='base cost'),
diff --git a/InvenTree/company/migrations/0045_alter_company_notes.py b/InvenTree/company/migrations/0045_alter_company_notes.py
new file mode 100644
index 000000000..3aefa54af
--- /dev/null
+++ b/InvenTree/company/migrations/0045_alter_company_notes.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.13 on 2022-06-20 11:23
+
+import InvenTree.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('company', '0044_auto_20220607_2204'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='company',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Company Notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+    ]
diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py
index 6702761cf..1a18d39d1 100644
--- a/InvenTree/company/models.py
+++ b/InvenTree/company/models.py
@@ -9,16 +9,16 @@ from django.core.validators import MinValueValidator
 from django.db import models
 from django.db.models import Q, Sum, UniqueConstraint
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 
-from markdownx.models import MarkdownxField
 from moneyed import CURRENCIES
 from stdimage.models import StdImageField
 
 import common.models
 import common.settings
+import InvenTree.fields
 import InvenTree.validators
 from common.settings import currency_code_default
 from InvenTree.fields import InvenTreeURLField
 from InvenTree.helpers import getBlankImage, getBlankThumbnail, getMediaUrl
 from InvenTree.models import InvenTreeAttachment
@@ -133,11 +133,11 @@ class Company(models.Model):
         },
         delete_orphans=True,
         verbose_name=_('Image'),
     )
 
-    notes = MarkdownxField(blank=True, verbose_name=_('Notes'))
+    notes = InvenTree.fields.InvenTreeNotesField(help_text=_("Company Notes"))
 
     is_customer = models.BooleanField(default=False, verbose_name=_('is customer'), help_text=_('Do you sell items to this company?'))
 
     is_supplier = models.BooleanField(default=True, verbose_name=_('is supplier'), help_text=_('Do you purchase items from this company?'))
 
diff --git a/InvenTree/order/migrations/0015_auto_20200201_2346.py b/InvenTree/order/migrations/0015_auto_20200201_2346.py
index 3407420fc..f59a05fcf 100644
--- a/InvenTree/order/migrations/0015_auto_20200201_2346.py
+++ b/InvenTree/order/migrations/0015_auto_20200201_2346.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-01 23:46
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='purchaseorder',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes'),
+            field=models.TextField(blank=True, help_text='Order notes'),
         ),
     ]
diff --git a/InvenTree/order/migrations/0020_auto_20200420_0940.py b/InvenTree/order/migrations/0020_auto_20200420_0940.py
index 59431353d..aef57a343 100644
--- a/InvenTree/order/migrations/0020_auto_20200420_0940.py
+++ b/InvenTree/order/migrations/0020_auto_20200420_0940.py
@@ -4,11 +4,10 @@ import InvenTree.fields
 import InvenTree.models
 from django.conf import settings
 import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -27,11 +26,11 @@ class Migration(migrations.Migration):
                 ('link', models.URLField(blank=True, help_text='Link to external page')),
                 ('creation_date', models.DateField(blank=True, null=True)),
                 ('status', models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Placed'), (30, 'Complete'), (40, 'Cancelled'), (50, 'Lost'), (60, 'Returned')], default=10, help_text='Order status')),
                 ('issue_date', models.DateField(blank=True, null=True)),
                 ('complete_date', models.DateField(blank=True, null=True)),
-                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Order notes')),
+                ('notes', models.TextField(blank=True, help_text='Order notes')),
                 ('customer_reference', models.CharField(blank=True, help_text='Customer order reference code', max_length=64)),
                 ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
                 ('customer', models.ForeignKey(help_text='Customer', limit_choices_to={True, 'is_supplier'}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sales_orders', to='company.Company')),
             ],
             options={
diff --git a/InvenTree/order/migrations/0044_auto_20210404_2016.py b/InvenTree/order/migrations/0044_auto_20210404_2016.py
index f683ce0aa..ef6923554 100644
--- a/InvenTree/order/migrations/0044_auto_20210404_2016.py
+++ b/InvenTree/order/migrations/0044_auto_20210404_2016.py
@@ -4,11 +4,10 @@ import InvenTree.fields
 import InvenTree.models
 from django.conf import settings
 import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -41,11 +40,11 @@ class Migration(migrations.Migration):
             field=models.URLField(blank=True, help_text='Link to external page', verbose_name='Link'),
         ),
         migrations.AlterField(
             model_name='purchaseorder',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
+            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='purchaseorder',
             name='received_by',
             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='received by'),
@@ -146,11 +145,11 @@ class Migration(migrations.Migration):
             field=models.URLField(blank=True, help_text='Link to external page', verbose_name='Link'),
         ),
         migrations.AlterField(
             model_name='salesorder',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
+            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='salesorder',
             name='reference',
             field=models.CharField(help_text='Order reference', max_length=64, unique=True, verbose_name='Reference'),
diff --git a/InvenTree/order/migrations/0053_salesordershipment.py b/InvenTree/order/migrations/0053_salesordershipment.py
index f36895c5e..85ab90f46 100644
--- a/InvenTree/order/migrations/0053_salesordershipment.py
+++ b/InvenTree/order/migrations/0053_salesordershipment.py
@@ -2,14 +2,10 @@
 
 from django.conf import settings
 from django.db import migrations, models
 import django.db.models.deletion
 
-import order.models
-
-import markdownx.models
-
 
 class Migration(migrations.Migration):
 
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@@ -21,11 +17,11 @@ class Migration(migrations.Migration):
             name='SalesOrderShipment',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('shipment_date', models.DateField(blank=True, help_text='Date of shipment', null=True, verbose_name='Shipment Date')),
                 ('reference', models.CharField(default='1', help_text='Shipment reference', max_length=100, verbose_name='Reference')),
-                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
+                ('notes', models.TextField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
                 ('checked_by', models.ForeignKey(blank=True, help_text='User who checked this shipment', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Checked By')),
                 ('order', models.ForeignKey(help_text='Sales Order', on_delete=django.db.models.deletion.CASCADE, related_name='shipments', to='order.salesorder', verbose_name='Order')),
             ],
         ),
     ]
diff --git a/InvenTree/order/migrations/0070_auto_20220620_0728.py b/InvenTree/order/migrations/0070_auto_20220620_0728.py
new file mode 100644
index 000000000..660a68fcc
--- /dev/null
+++ b/InvenTree/order/migrations/0070_auto_20220620_0728.py
@@ -0,0 +1,29 @@
+# Generated by Django 3.2.13 on 2022-06-20 07:28
+
+import InvenTree.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('order', '0069_auto_20220524_0508'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='purchaseorder',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+        migrations.AlterField(
+            model_name='salesorder',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+        migrations.AlterField(
+            model_name='salesordershipment',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Shipment notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+    ]
diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py
index bdced458c..2f82d6af9 100644
--- a/InvenTree/order/models.py
+++ b/InvenTree/order/models.py
@@ -18,19 +18,19 @@ from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 
 from djmoney.contrib.exchange.exceptions import MissingRate
 from djmoney.contrib.exchange.models import convert_money
 from djmoney.money import Money
-from markdownx.models import MarkdownxField
 from mptt.models import TreeForeignKey
 
 import InvenTree.helpers
 import InvenTree.ready
 from common.settings import currency_code_default
 from company.models import Company, SupplierPart
 from InvenTree.exceptions import log_error
-from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
+from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
+                              RoundingDecimalField)
 from InvenTree.helpers import (decimal2string, getSetting, increment,
                                notify_responsible)
 from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
 from InvenTree.status_codes import (PurchaseOrderStatus, SalesOrderStatus,
                                     StockHistoryCode, StockStatus)
@@ -150,11 +150,11 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
         help_text=_('User or group responsible for this order'),
         verbose_name=_('Responsible'),
         related_name='+',
     )
 
-    notes = MarkdownxField(blank=True, verbose_name=_('Notes'), help_text=_('Order notes'))
+    notes = InvenTreeNotesField(help_text=_('Order notes'))
 
     def get_total_price(self, target_currency=None):
         """Calculates the total price of all order lines, and converts to the specified target currency.
 
         If not specified, the default system currency is used.
@@ -1208,15 +1208,11 @@ class SalesOrderShipment(models.Model):
         verbose_name=('Shipment'),
         help_text=_('Shipment number'),
         default='1',
     )
 
-    notes = MarkdownxField(
-        blank=True,
-        verbose_name=_('Notes'),
-        help_text=_('Shipment notes'),
-    )
+    notes = InvenTreeNotesField(help_text=_('Shipment notes'))
 
     tracking_number = models.CharField(
         max_length=100,
         blank=True,
         unique=False,
diff --git a/InvenTree/part/migrations/0026_auto_20200131_1022.py b/InvenTree/part/migrations/0026_auto_20200131_1022.py
index f3a3af73a..c0f1ead30 100644
--- a/InvenTree/part/migrations/0026_auto_20200131_1022.py
+++ b/InvenTree/part/migrations/0026_auto_20200131_1022.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-01-31 10:22
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='part',
             name='notes',
-            field=markdownx.models.MarkdownxField(help_text='Part notes - supports Markdown formatting'),
+            field=models.TextField(help_text='Part notes - supports Markdown formatting'),
         ),
     ]
diff --git a/InvenTree/part/migrations/0029_auto_20200223_0901.py b/InvenTree/part/migrations/0029_auto_20200223_0901.py
index 2ed86c510..c0db32fb6 100644
--- a/InvenTree/part/migrations/0029_auto_20200223_0901.py
+++ b/InvenTree/part/migrations/0029_auto_20200223_0901.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-23 09:01
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='part',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting'),
+            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting'),
         ),
     ]
diff --git a/InvenTree/part/migrations/0048_auto_20200902_1404.py b/InvenTree/part/migrations/0048_auto_20200902_1404.py
index bd163fa41..4f3584f3c 100644
--- a/InvenTree/part/migrations/0048_auto_20200902_1404.py
+++ b/InvenTree/part/migrations/0048_auto_20200902_1404.py
@@ -1,12 +1,10 @@
 # Generated by Django 3.0.7 on 2020-09-02 14:04
 
 import InvenTree.fields
 import InvenTree.validators
 
-import markdownx
-
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
@@ -36,11 +34,11 @@ class Migration(migrations.Migration):
             field=models.CharField(blank=True, help_text='Part revision or version number', max_length=100, null=True),
         ),
         migrations.AlterField(
             model_name='part',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
+            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
         ),
         migrations.AlterField(
             model_name='part',
             name='units',
             field=models.CharField(blank=True, default='', help_text='Stock keeping units for this part', max_length=20, null=True),
diff --git a/InvenTree/part/migrations/0061_auto_20210103_2313.py b/InvenTree/part/migrations/0061_auto_20210103_2313.py
index ca0c2a277..502ff7c8e 100644
--- a/InvenTree/part/migrations/0061_auto_20210103_2313.py
+++ b/InvenTree/part/migrations/0061_auto_20210103_2313.py
@@ -2,11 +2,10 @@
 
 import InvenTree.fields
 import InvenTree.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 import mptt.fields
 import part.settings
 
 
 class Migration(migrations.Migration):
@@ -63,11 +62,11 @@ class Migration(migrations.Migration):
             field=models.CharField(help_text='Part name', max_length=100, validators=[InvenTree.validators.validate_part_name], verbose_name='Name'),
         ),
         migrations.AlterField(
             model_name='part',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
+            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='part',
             name='revision',
             field=models.CharField(blank=True, help_text='Part revision or version number', max_length=100, null=True, verbose_name='Revision'),
diff --git a/InvenTree/part/migrations/0079_alter_part_notes.py b/InvenTree/part/migrations/0079_alter_part_notes.py
new file mode 100644
index 000000000..7d4cd5b80
--- /dev/null
+++ b/InvenTree/part/migrations/0079_alter_part_notes.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.13 on 2022-06-20 07:28
+
+import InvenTree.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('part', '0078_auto_20220606_0024'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='part',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Part notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+    ]
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 219a8f71c..4c02ee34f 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -23,11 +23,10 @@ from django.utils.translation import gettext_lazy as _
 
 from django_cleanup import cleanup
 from djmoney.contrib.exchange.exceptions import MissingRate
 from djmoney.contrib.exchange.models import convert_money
 from jinja2 import Template
-from markdownx.models import MarkdownxField
 from mptt.exceptions import InvalidMove
 from mptt.managers import TreeManager
 from mptt.models import MPTTModel, TreeForeignKey
 from stdimage.models import StdImageField
 
@@ -39,11 +38,11 @@ import part.settings as part_settings
 from build import models as BuildModels
 from common.models import InvenTreeSetting
 from common.settings import currency_code_default
 from company.models import SupplierPart
 from InvenTree import helpers, validators
-from InvenTree.fields import InvenTreeURLField
+from InvenTree.fields import InvenTreeNotesField, InvenTreeURLField
 from InvenTree.helpers import decimal2money, decimal2string, normalize
 from InvenTree.models import (DataImportMixin, InvenTreeAttachment,
                               InvenTreeTree)
 from InvenTree.status_codes import (BuildStatus, PurchaseOrderStatus,
                                     SalesOrderStatus)
@@ -918,15 +917,11 @@ class Part(MetadataMixin, MPTTModel):
     virtual = models.BooleanField(
         default=part_settings.part_virtual_default,
         verbose_name=_('Virtual'),
         help_text=_('Is this a virtual part, such as a software product or license?'))
 
-    notes = MarkdownxField(
-        blank=True, null=True,
-        verbose_name=_('Notes'),
-        help_text=_('Part notes - supports Markdown formatting')
-    )
+    notes = InvenTreeNotesField(help_text=_('Part notes'))
 
     bom_checksum = models.CharField(max_length=128, blank=True, verbose_name=_('BOM checksum'), help_text=_('Stored BOM checksum'))
 
     bom_checked_by = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True,
                                        verbose_name=_('BOM checked by'), related_name='boms_checked')
diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py
index eb7364eca..b39f4f2e1 100644
--- a/InvenTree/part/test_api.py
+++ b/InvenTree/part/test_api.py
@@ -1303,10 +1303,26 @@ class PartDetailTests(InvenTreeAPITestCase):
 
         self.assertFalse('foo' in part.metadata)
         self.assertFalse('hello' in part.metadata)
         self.assertEqual(part.metadata['x'], 'y')
 
+    def test_part_notes(self):
+        """Unit tests for the part 'notes' field"""
+
+        # Ensure that we cannot upload a very long piece of text
+        url = reverse('api-part-detail', kwargs={'pk': 1})
+
+        response = self.patch(
+            url,
+            {
+                'notes': 'abcde' * 10001
+            },
+            expected_code=400
+        )
+
+        self.assertIn('Ensure this field has no more than 50000 characters', str(response.data['notes']))
+
 
 class PartAPIAggregationTest(InvenTreeAPITestCase):
     """Tests to ensure that the various aggregation annotations are working correctly..."""
 
     fixtures = [
diff --git a/InvenTree/stock/migrations/0018_auto_20200202_0103.py b/InvenTree/stock/migrations/0018_auto_20200202_0103.py
index 9cf90ceeb..50bccf6e1 100644
--- a/InvenTree/stock/migrations/0018_auto_20200202_0103.py
+++ b/InvenTree/stock/migrations/0018_auto_20200202_0103.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-02 01:03
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='stockitem',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes'),
+            field=models.TextField(blank=True, help_text='Stock Item Notes'),
         ),
     ]
diff --git a/InvenTree/stock/migrations/0020_auto_20200206_1213.py b/InvenTree/stock/migrations/0020_auto_20200206_1213.py
index 34be29fd3..e36bc6a0c 100644
--- a/InvenTree/stock/migrations/0020_auto_20200206_1213.py
+++ b/InvenTree/stock/migrations/0020_auto_20200206_1213.py
@@ -1,9 +1,8 @@
 # Generated by Django 2.2.9 on 2020-02-06 12:13
 
-from django.db import migrations
-import markdownx.models
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -12,8 +11,8 @@ class Migration(migrations.Migration):
 
     operations = [
         migrations.AlterField(
             model_name='stockitem',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True),
+            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True),
         ),
     ]
diff --git a/InvenTree/stock/migrations/0034_auto_20200426_0602.py b/InvenTree/stock/migrations/0034_auto_20200426_0602.py
index 4bf3171aa..53a44a695 100644
--- a/InvenTree/stock/migrations/0034_auto_20200426_0602.py
+++ b/InvenTree/stock/migrations/0034_auto_20200426_0602.py
@@ -2,11 +2,10 @@
 
 import InvenTree.fields
 import django.core.validators
 from django.db import migrations, models
 import django.db.models.deletion
-import markdownx.models
 import mptt.fields
 
 
 class Migration(migrations.Migration):
 
@@ -54,11 +53,11 @@ class Migration(migrations.Migration):
             field=mptt.fields.TreeForeignKey(blank=True, help_text='Where is this stock item located?', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='stock_items', to='stock.StockLocation', verbose_name='Stock Location'),
         ),
         migrations.AlterField(
             model_name='stockitem',
             name='notes',
-            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
+            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
         ),
         migrations.AlterField(
             model_name='stockitem',
             name='parent',
             field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='stock.StockItem', verbose_name='Parent Stock Item'),
diff --git a/InvenTree/stock/migrations/0077_alter_stockitem_notes.py b/InvenTree/stock/migrations/0077_alter_stockitem_notes.py
new file mode 100644
index 000000000..5ea7834d7
--- /dev/null
+++ b/InvenTree/stock/migrations/0077_alter_stockitem_notes.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.13 on 2022-06-20 07:28
+
+import InvenTree.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('stock', '0076_alter_stockitem_status'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='stockitem',
+            name='notes',
+            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Stock Item Notes', max_length=50000, null=True, verbose_name='Notes'),
+        ),
+    ]
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
index 5093ce9bc..2f4e73521 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -16,22 +16,22 @@ from django.db.models.signals import post_delete, post_save, pre_delete
 from django.dispatch import receiver
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 
 from jinja2 import Template
-from markdownx.models import MarkdownxField
 from mptt.managers import TreeManager
 from mptt.models import MPTTModel, TreeForeignKey
 
 import common.models
 import InvenTree.helpers
 import InvenTree.ready
 import InvenTree.tasks
 import label.models
 import report.models
 from company import models as CompanyModels
-from InvenTree.fields import InvenTreeModelMoneyField, InvenTreeURLField
+from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
+                              InvenTreeURLField)
 from InvenTree.models import InvenTreeAttachment, InvenTreeTree
 from InvenTree.serializers import extract_int
 from InvenTree.status_codes import StockHistoryCode, StockStatus
 from part import models as PartModels
 from plugin.events import trigger_event
@@ -706,15 +706,11 @@ class StockItem(MetadataMixin, MPTTModel):
     status = models.PositiveIntegerField(
         default=StockStatus.OK,
         choices=StockStatus.items(),
         validators=[MinValueValidator(0)])
 
-    notes = MarkdownxField(
-        blank=True, null=True,
-        verbose_name=_("Notes"),
-        help_text=_('Stock Item Notes')
-    )
+    notes = InvenTreeNotesField(help_text=_('Stock Item Notes'))
 
     purchase_price = InvenTreeModelMoneyField(
         max_digits=19,
         decimal_places=4,
         blank=True,
diff --git a/requirements.txt b/requirements.txt
index eb908235e..9684c63b3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,11 +17,10 @@ django-error-report==0.2.0              # Error report viewer for the admin inte
 django-filter==2.4.0                    # Extended filtering options
 django-formtools==2.3                   # Form wizard tools
 django-import-export==2.5.0             # Data import / export for admin interface
 django-maintenance-mode==0.16.1         # Shut down application while reloading etc.
 django-markdownify==0.8.0               # Markdown rendering
-django-markdownx==3.0.1                 # Markdown form fields
 django-money==1.1                       # Django app for currency management
 django-mptt==0.11.0                     # Modified Preorder Tree Traversal
 django-redis>=5.0.0                     # Redis integration
 django-q==1.3.4                         # Background task scheduling
 django-sql-utils==0.5.0                 # Advanced query annotation / aggregation

Vulnerable code: from datetime import datetime
    'markdownx',                            # Markdown editing
# Markdownx configuration
# Ref: https://neutronx.github.io/django-markdownx/customization/
MARKDOWNX_MEDIA_PATH = datetime.now().strftime('markdownx/%Y/%m/%d')

.markdownx .row {
    border-color: rgb(31, 31, 92);
}
.markdownx-editor {
    border-color: rgb(31, 31, 92);
}
.markdownx-preview {
    border-color: rgb(31, 31, 92);
}
.markdownx .row {
    margin: 5px;
    padding: 5px;
    border: 1px solid #cce;
    border-radius: 4px;
}

.markdownx-editor {
    width: 100%;
    border: 1px solid #cce;
    border-radius: 3px;
    padding: 10px;
}

.markdownx-preview {
    border: 1px solid #cce;
    border-radius: 3px;
    padding: 10px;
}


    # 3rd party endpoints
    re_path(r'^markdownx/', include('markdownx.urls')),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes'),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
from markdownx.models import MarkdownxField

    notes = MarkdownxField(
        verbose_name=_('Notes'),
        blank=True, help_text=_('Extra build notes')
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
    notes = MarkdownxField(blank=True, verbose_name=_('Notes'))
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes'),
import markdownx.models
                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Order notes')),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
            field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'),
import order.models

import markdownx.models

                ('notes', markdownx.models.MarkdownxField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
    notes = MarkdownxField(blank=True, verbose_name=_('Notes'), help_text=_('Order notes'))
    notes = MarkdownxField(
        blank=True,
        verbose_name=_('Notes'),
        help_text=_('Shipment notes'),
    )
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(help_text='Part notes - supports Markdown formatting'),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting'),
import markdownx

            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeURLField
    notes = MarkdownxField(
        blank=True, null=True,
        verbose_name=_('Notes'),
        help_text=_('Part notes - supports Markdown formatting')
    )
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes'),
from django.db import migrations
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True),
import markdownx.models
            field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
from markdownx.models import MarkdownxField
from InvenTree.fields import InvenTreeModelMoneyField, InvenTreeURLField
    notes = MarkdownxField(
        blank=True, null=True,
        verbose_name=_("Notes"),
        help_text=_('Stock Item Notes')
    )
django-markdownx==3.0.1                 # Markdown form fields
Fixed code: 

class InvenTreeNotesField(models.TextField):
    """Custom implementation of a 'notes' field"""

    # Maximum character limit for the various 'notes' fields
    NOTES_MAX_LENGTH = 50000

    def __init__(self, **kwargs):
        """Configure default initial values for this field"""
        kwargs['max_length'] = self.NOTES_MAX_LENGTH
        kwargs['verbose_name'] = _('Notes')
        kwargs['blank'] = True
        kwargs['null'] = True

        super().__init__(**kwargs)
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Extra build notes'),
            field=models.TextField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('build', '0034_alter_build_reference_int'),
    ]

    operations = [
        migrations.AlterField(
            model_name='build',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Extra build notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
    notes = InvenTree.fields.InvenTreeNotesField(
        help_text=_('Extra build notes')
from django.db import migrations, models
            field=models.TextField(blank=True),
            field=models.TextField(blank=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 11:23

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('company', '0044_auto_20220607_2204'),
    ]

    operations = [
        migrations.AlterField(
            model_name='company',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Company Notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
import InvenTree.fields
    notes = InvenTree.fields.InvenTreeNotesField(help_text=_("Company Notes"))
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Order notes'),
                ('notes', models.TextField(blank=True, help_text='Order notes')),
            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
            field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
                ('notes', models.TextField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('order', '0069_auto_20220524_0508'),
    ]

    operations = [
        migrations.AlterField(
            model_name='purchaseorder',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
        migrations.AlterField(
            model_name='salesorder',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
        migrations.AlterField(
            model_name='salesordershipment',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Shipment notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
                              RoundingDecimalField)
    notes = InvenTreeNotesField(help_text=_('Order notes'))
    notes = InvenTreeNotesField(help_text=_('Shipment notes'))
from django.db import migrations, models
            field=models.TextField(help_text='Part notes - supports Markdown formatting'),
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting'),
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
            field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('part', '0078_auto_20220606_0024'),
    ]

    operations = [
        migrations.AlterField(
            model_name='part',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Part notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import InvenTreeNotesField, InvenTreeURLField
    notes = InvenTreeNotesField(help_text=_('Part notes'))
    def test_part_notes(self):
        """Unit tests for the part 'notes' field"""

        # Ensure that we cannot upload a very long piece of text
        url = reverse('api-part-detail', kwargs={'pk': 1})

        response = self.patch(
            url,
            {
                'notes': 'abcde' * 10001
            },
            expected_code=400
        )

        self.assertIn('Ensure this field has no more than 50000 characters', str(response.data['notes']))

from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Stock Item Notes'),
from django.db import migrations, models
            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True),
            field=models.TextField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
# Generated by Django 3.2.13 on 2022-06-20 07:28

import InvenTree.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('stock', '0076_alter_stockitem_status'),
    ]

    operations = [
        migrations.AlterField(
            model_name='stockitem',
            name='notes',
            field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Stock Item Notes', max_length=50000, null=True, verbose_name='Notes'),
        ),
    ]
from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
                              InvenTreeURLField)
    notes = InvenTreeNotesField(help_text=_('Stock Item Notes'))