diff --git a/catalog/common/models.py b/catalog/common/models.py index 03d223a3..825f16f5 100644 --- a/catalog/common/models.py +++ b/catalog/common/models.py @@ -240,6 +240,7 @@ class ItemSchema(ItemInSchema, BaseSchema): class Item(SoftDeleteMixin, PolymorphicModel): url_path = None # subclass must specify this type = None # subclass must specify this + parent_class = None # subclass may specify this to allow create child item category = None # subclass must specify this demonstrative = None # subclass must specify this uid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True) @@ -307,6 +308,9 @@ class Item(SoftDeleteMixin, PolymorphicModel): def parent_item(self): return None + def set_parent_item(self, value): + raise ValueError("cannot set parent item") + @property def parent_uuid(self): return self.parent_item.uuid if self.parent_item else None diff --git a/catalog/performance/models.py b/catalog/performance/models.py index 15566261..4ddbe861 100644 --- a/catalog/performance/models.py +++ b/catalog/performance/models.py @@ -34,6 +34,7 @@ _ACTOR_SCHEMA = { class Performance(Item): type = ItemType.Performance + child_class = "PerformanceProduction" category = ItemCategory.Performance url_path = "performance" demonstrative = _("这部剧作") @@ -300,9 +301,13 @@ class PerformanceProduction(Item): def parent_item(self): return self.show + def set_parent_item(self, value): + print("set", value) + self.show = value + @property def display_title(self): - return f"{self.show.title} {self.title}" + return f"{self.show.title if self.show else '♢'} {self.title}" @property def cover_image_url(self): @@ -310,6 +315,8 @@ class PerformanceProduction(Item): self.cover.url if self.cover and self.cover != DEFAULT_ITEM_COVER else self.show.cover_image_url + if self.show + else None ) def update_linked_items_from_external_resource(self, resource): diff --git a/catalog/templates/_sidebar_edit.html b/catalog/templates/_sidebar_edit.html index 7ff10187..2869b488 100644 --- a/catalog/templates/_sidebar_edit.html +++ b/catalog/templates/_sidebar_edit.html @@ -29,6 +29,15 @@ {% endfor %} + {% if item.child_class %} +
+ {% trans '新建子条目' %} +
+ + +
+
+ {% endif %} {% if item.class_name == "movie" or item.class_name == "tvshow" %}
{% trans '切换分类' %} diff --git a/catalog/templates/catalog_edit.html b/catalog/templates/catalog_edit.html index 661b1122..f9e2fa3e 100644 --- a/catalog/templates/catalog_edit.html +++ b/catalog/templates/catalog_edit.html @@ -38,8 +38,7 @@
{% if item.is_deleted %}条目已被删除{% endif %} {% if item.merged_to_item %}条目已被合并{% endif %} -
{% csrf_token %} diff --git a/catalog/templates/search_sidebar.html b/catalog/templates/search_sidebar.html index fa83d3b6..5185545c 100644 --- a/catalog/templates/search_sidebar.html +++ b/catalog/templates/search_sidebar.html @@ -20,25 +20,25 @@

当然也可以手工创建条目:

diff --git a/catalog/tv/models.py b/catalog/tv/models.py index 3b407df0..e3c7496b 100644 --- a/catalog/tv/models.py +++ b/catalog/tv/models.py @@ -72,6 +72,7 @@ class TVSeasonSchema(TVSeasonInSchema, BaseSchema): class TVShow(Item): type = ItemType.TVShow + child_class = "TVSeason" category = ItemCategory.TV url_path = "tv" demonstrative = _("这部剧集") @@ -351,6 +352,9 @@ class TVSeason(Item): def parent_item(self): return self.show + def set_parent_item(self, value): + self.show = value + class TVEpisode(Item): category = ItemCategory.TV diff --git a/catalog/views.py b/catalog/views.py index 84b4c49a..069183dd 100644 --- a/catalog/views.py +++ b/catalog/views.py @@ -124,11 +124,15 @@ def retrieve(request, item_path, item_uuid): @login_required def create(request, item_model): + form_cls = CatalogForms.get(item_model) + if not form_cls: + raise BadRequest("Invalid item type") if request.method == "GET": - form_cls = CatalogForms.get(item_model) - if not form_cls: - raise BadRequest() - form = form_cls() + form = form_cls( + initial={ + "title": request.GET.get("title", ""), + } + ) return render( request, "catalog_edit.html", @@ -137,19 +141,27 @@ def create(request, item_model): }, ) elif request.method == "POST": - form_cls = CatalogForms.get(item_model) - if not form_cls: - raise BadRequest() form = form_cls(request.POST, request.FILES) + parent = None + if request.GET.get("parent", ""): + parent = get_object_or_404( + Item, uid=get_uuid_or_404(request.GET.get("parent", "")) + ) + if parent.child_class != form.instance.__class__.__name__: + raise BadRequest( + f"Invalid parent type: {form.instance.__class__} -> {parent.__class__}" + ) if form.is_valid(): form.instance.last_editor = request.user form.instance.edited_time = timezone.now() + if parent: + form.instance.set_parent_item(parent) form.instance.save() return redirect(form.instance.url) else: raise BadRequest(form.errors) else: - raise BadRequest() + raise BadRequest("Invalid request method") @login_required