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
This commit is contained in:
Oliver 2022-06-20 22:20:04 +10:00 committed by GitHub
parent a8b71d7d9e
commit 63b4ff3eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 173 additions and 110 deletions

View File

@ -157,3 +157,19 @@ 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)

View File

@ -15,7 +15,6 @@ import random
import socket
import string
import sys
from datetime import datetime
import django.conf.locale
from django.core.files.storage import default_storage
@ -253,7 +252,6 @@ INSTALLED_APPS = [
'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
@ -875,10 +873,6 @@ ACCOUNT_ADAPTER = 'InvenTree.forms.CustomAccountAdapter'
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

View File

@ -3539,15 +3539,6 @@ a.ui-button:active,
.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);

View File

@ -63,30 +63,10 @@ main {
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 {

View File

@ -126,9 +126,6 @@ backendpatterns = [
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 = [

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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'),
),
]

View File

@ -4,7 +4,6 @@ import InvenTree.fields
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import markdownx.models
import mptt.fields
@ -31,7 +30,7 @@ class Migration(migrations.Migration):
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',

View File

@ -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'),
),
]

View File

@ -16,8 +16,6 @@ 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
@ -320,9 +318,8 @@ class Build(MPTTModel, ReferenceIndexingMixin):
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):

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='company',
name='notes',
field=markdownx.models.MarkdownxField(blank=True),
field=models.TextField(blank=True),
),
]

View File

@ -5,7 +5,6 @@ import company.models
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import markdownx.models
import stdimage.models
@ -44,7 +43,7 @@ class Migration(migrations.Migration):
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',

View File

@ -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'),
),
]

View File

@ -11,12 +11,12 @@ 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
@ -135,7 +135,7 @@ class Company(models.Model):
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?'))

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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'),
),
]

View File

@ -6,7 +6,6 @@ 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):
@ -29,7 +28,7 @@ class Migration(migrations.Migration):
('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')),

View File

@ -6,7 +6,6 @@ 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):
@ -43,7 +42,7 @@ class Migration(migrations.Migration):
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',
@ -148,7 +147,7 @@ class Migration(migrations.Migration):
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',

View File

@ -4,10 +4,6 @@ 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):
@ -23,7 +19,7 @@ class Migration(migrations.Migration):
('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')),
],

View File

@ -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'),
),
]

View File

@ -20,7 +20,6 @@ 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
@ -28,7 +27,8 @@ 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
@ -152,7 +152,7 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
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.
@ -1210,11 +1210,7 @@ class SalesOrderShipment(models.Model):
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,

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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'),
),
]

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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'),
),
]

View File

@ -3,8 +3,6 @@
import InvenTree.fields
import InvenTree.validators
import markdownx
from django.db import migrations, models
@ -38,7 +36,7 @@ class Migration(migrations.Migration):
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',

View File

@ -4,7 +4,6 @@ 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
@ -65,7 +64,7 @@ class Migration(migrations.Migration):
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',

View File

@ -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'),
),
]

View File

@ -25,7 +25,6 @@ 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
@ -41,7 +40,7 @@ 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)
@ -920,11 +919,7 @@ class Part(MetadataMixin, MPTTModel):
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'))

View File

@ -1305,6 +1305,22 @@ class PartDetailTests(InvenTreeAPITestCase):
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..."""

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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'),
),
]

View File

@ -1,7 +1,6 @@
# 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):
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
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),
),
]

View File

@ -4,7 +4,6 @@ import InvenTree.fields
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import markdownx.models
import mptt.fields
@ -56,7 +55,7 @@ class Migration(migrations.Migration):
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',

View File

@ -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'),
),
]

View File

@ -18,7 +18,6 @@ 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
@ -29,7 +28,8 @@ 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
@ -708,11 +708,7 @@ class StockItem(MetadataMixin, MPTTModel):
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,

View File

@ -19,7 +19,6 @@ 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