create child item

This commit is contained in:
Your Name 2023-06-05 18:57:52 -04:00 committed by Henri Dickson
parent dedab31fe0
commit 0a3def4eeb
7 changed files with 53 additions and 18 deletions

View file

@ -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

View file

@ -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):

View file

@ -29,6 +29,15 @@
</div>
</details>
{% endfor %}
{% if item.child_class %}
<details>
<summary>{% trans '新建子条目' %}</summary>
<form method="get" action="{% url 'catalog:create' item.child_class %}">
<input name="parent" type=hidden value="{{ item.uuid }}">
<input class="contrast" type="submit" value="{{ item.child_class }}">
</form>
</details>
{% endif %}
{% if item.class_name == "movie" or item.class_name == "tvshow" %}
<details>
<summary>{% trans '切换分类' %}</summary>

View file

@ -38,8 +38,7 @@
<div class="grid__main">
{% if item.is_deleted %}<i>条目已被删除</i>{% endif %}
{% if item.merged_to_item %}<i>条目已被合并</i>{% endif %}
<form action="{{ submit_url }}"
method="post"
<form method="post"
enctype="multipart/form-data"
_=" init set .rjf-add-button's innerHTML to '' end">
{% csrf_token %}

View file

@ -20,25 +20,25 @@
<p>当然也可以手工创建条目:</p>
<ul>
<li>
<a href="{% url 'catalog:create' 'Edition' %}">{% trans '添加图书' %}</a>
<a href="{% url 'catalog:create' 'Edition' %}?title={{ request.GET.q | default:'' }}">{% trans '添加图书' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'Movie' %}">{% trans '添加电影' %}</a>
<a href="{% url 'catalog:create' 'Movie' %}?title={{ request.GET.q | default:'' }}">{% trans '添加电影' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'TVShow' %}">{% trans '添加剧集' %}</a>
<a href="{% url 'catalog:create' 'TVShow' %}?title={{ request.GET.q | default:'' }}">{% trans '添加电视剧集' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'Podcast' %}">{% trans '添加播客' %}</a>
<a href="{% url 'catalog:create' 'Podcast' %}?title={{ request.GET.q | default:'' }}">{% trans '添加播客' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'Album' %}">{% trans '添加专辑' %}</a>
<a href="{% url 'catalog:create' 'Album' %}?title={{ request.GET.q | default:'' }}">{% trans '添加音乐专辑' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'Game' %}">{% trans '添加游戏' %}</a>
<a href="{% url 'catalog:create' 'Game' %}?title={{ request.GET.q | default:'' }}">{% trans '添加游戏' %}</a>
</li>
<li>
<a href="{% url 'catalog:create' 'Performance' %}">{% trans '添加剧目' %}</a>
<a href="{% url 'catalog:create' 'Performance' %}?title={{ request.GET.q | default:'' }}">{% trans '添加表演或戏剧作品' %}</a>
</li>
</ul>
</article>

View file

@ -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

View file

@ -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