mirror of
https://github.com/inventree/InvenTree.git
synced 2026-06-14 20:40:45 +00:00
432e0c622c
* Add basic model for handling generic attachments * Refactor migration * Data migration to convert old files across * Admin updates * Increase comment field max_length * Adjust field name * Remove legacy serializer classes / endpoints * Expose new model to API * Admin site list filters * Remove legacy attachment models - Add new mixin class to designate which models can have attachments * Update data migration - Ensure other apps are at the correct migration state beforehand * Add migrations to remove legacy attachment tables * Fix for "rename_attachment" callback * Refactor model_type field - ContentType does not allow easy API serialization * Set allowed options for admin * Update model verbose names * Fix logic for file upload * Add choices for serializer * Add API filtering * Fix for API filter * Fix for attachment tables in PUI - Still not solved permission issues * Bump API version * Record user when uploading attachment via API * Refactor <AttachmentTable /> for PUI * Display 'file_size' in PUI attachment table * Fix company migrations * Include permission informtion in roles API endpoint * Read user permissions in PUI * Simplify permission checks for <AttachmentTable /> * Automatically clean up old content types * Cleanup PUI * Fix typo in data migration * Add reverse data migration * Update unit tests * Use InMemoryStorage for media files in test mode * Data migration unit test * Fix "model_type" field - It is a required field after all * Add permission check for serializer * Fix permission check for CUI * Fix PUI import * Test python lib against specific branch - Will be reverted once code is merged * Revert STORAGES setting - Might be worth looking into again * Fix part unit test * Fix unit test for sales order * Use 'get_global_setting' * Use 'get_global_setting' * Update setting getter * Unit tests * Tweaks * Revert change to settings.py * More updates for get_global_setting * Relax API query count requirement * remove illegal chars and add unit tests * Fix unit tests * Fix frontend unit tests * settings management updates * Prevent db write under more conditions * Simplify settings code * Pop values before creating filters * Prevent settings write under certain conditions * Add debug msg * Clear db on record import * Refactor permissions checks - Allows extension / customization of permission checks at a later date * Unit test updates * Prevent delete of attachment without correct permissions * Adjust odcker.yaml * Cleanup data migrations * Tweak migration tests for build app * Update data migration - Handle case with missing data * Prevent debug shell in TESTING mode * Update migration dependencies - Ensure all apps are "up to date" before removing legacy tables * add file size test * Update migration tests * Revert some settings caching changes * Fix incorrect logic in migration * Update unit tests * Prevent create on CURRENCY_CODES - Seems to play havoc with bootup sequence * Fix unit test * Some refactoring - Use get_global_setting * Fix typo * Revert change * Add "tags" and "metadata" * Include "tags" field in API serializer * add "metadata" endpoint for attachments
123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
# Generated by Django 4.2.12 on 2024-06-08 12:38
|
|
|
|
from django.db import migrations
|
|
from django.core.files.storage import default_storage
|
|
|
|
|
|
def get_legacy_models():
|
|
"""Return a set of legacy attachment models."""
|
|
|
|
# Legacy attachment types to convert:
|
|
# app_label, table name, target model, model ref
|
|
return [
|
|
('build', 'BuildOrderAttachment', 'build', 'build'),
|
|
('company', 'CompanyAttachment', 'company', 'company'),
|
|
('company', 'ManufacturerPartAttachment', 'manufacturerpart', 'manufacturer_part'),
|
|
('order', 'PurchaseOrderAttachment', 'purchaseorder', 'order'),
|
|
('order', 'SalesOrderAttachment', 'salesorder', 'order'),
|
|
('order', 'ReturnOrderAttachment', 'returnorder', 'order'),
|
|
('part', 'PartAttachment', 'part', 'part'),
|
|
('stock', 'StockItemAttachment', 'stockitem', 'stock_item')
|
|
]
|
|
|
|
|
|
def update_attachments(apps, schema_editor):
|
|
"""Migrate any existing attachment models to the new attachment table."""
|
|
|
|
Attachment = apps.get_model('common', 'attachment')
|
|
|
|
N = 0
|
|
|
|
for app, model, target_model, model_ref in get_legacy_models():
|
|
LegacyAttachmentModel = apps.get_model(app, model)
|
|
|
|
if LegacyAttachmentModel.objects.count() == 0:
|
|
continue
|
|
|
|
to_create = []
|
|
|
|
for attachment in LegacyAttachmentModel.objects.all():
|
|
|
|
# Find the size of the file (if exists)
|
|
if attachment.attachment and default_storage.exists(attachment.attachment.name):
|
|
try:
|
|
file_size = default_storage.size(attachment.attachment.name)
|
|
except NotImplementedError:
|
|
file_size = 0
|
|
else:
|
|
file_size = 0
|
|
|
|
to_create.append(
|
|
Attachment(
|
|
model_type=target_model,
|
|
model_id=getattr(attachment, model_ref).pk,
|
|
attachment=attachment.attachment,
|
|
link=attachment.link,
|
|
comment=attachment.comment,
|
|
upload_date=attachment.upload_date,
|
|
upload_user=attachment.user,
|
|
file_size=file_size
|
|
)
|
|
)
|
|
|
|
if len(to_create) > 0:
|
|
print(f"Migrating {len(to_create)} attachments for the legacy '{model}' model.")
|
|
Attachment.objects.bulk_create(to_create)
|
|
|
|
N += len(to_create)
|
|
|
|
# Check the correct number of Attachment objects has been created
|
|
assert(N == Attachment.objects.count())
|
|
|
|
|
|
def reverse_attachments(apps, schema_editor):
|
|
"""Reverse data migration, and map new Attachment model back to legacy models."""
|
|
|
|
Attachment = apps.get_model('common', 'attachment')
|
|
|
|
N = 0
|
|
|
|
for app, model, target_model, model_ref in get_legacy_models():
|
|
LegacyAttachmentModel = apps.get_model(app, model)
|
|
|
|
to_create = []
|
|
|
|
for attachment in Attachment.objects.filter(model_type=target_model):
|
|
|
|
TargetModel = apps.get_model(app, target_model)
|
|
|
|
data = {
|
|
'attachment': attachment.attachment,
|
|
'link': attachment.link,
|
|
'comment': attachment.comment,
|
|
'upload_date': attachment.upload_date,
|
|
'user': attachment.upload_user,
|
|
model_ref: TargetModel.objects.get(pk=attachment.model_id)
|
|
}
|
|
|
|
to_create.append(LegacyAttachmentModel(**data))
|
|
|
|
if len(to_create) > 0:
|
|
print(f"Reversing {len(to_create)} attachments for the legacy '{model}' model.")
|
|
LegacyAttachmentModel.objects.bulk_create(to_create)
|
|
|
|
N += len(to_create)
|
|
|
|
# Check the correct number of LegacyAttachmentModel objects has been created
|
|
assert(N == Attachment.objects.count())
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('build', '0050_auto_20240508_0138'),
|
|
('common', '0025_attachment'),
|
|
('company', '0069_company_active'),
|
|
('order', '0099_alter_salesorder_status'),
|
|
('part', '0123_parttesttemplate_choices'),
|
|
('stock', '0110_alter_stockitemtestresult_finished_datetime_and_more')
|
|
]
|
|
|
|
operations = [
|
|
migrations.RunPython(update_attachments, reverse_code=reverse_attachments),
|
|
]
|