edit mark

This commit is contained in:
Your Name 2022-12-23 00:08:42 -05:00
parent c706c7f10e
commit 744413b2fc
12 changed files with 350 additions and 174 deletions

View file

@ -10,7 +10,7 @@ from simple_history.models import HistoricalRecords
import uuid
from .utils import DEFAULT_ITEM_COVER, item_cover_path
from .mixins import SoftDeleteMixin
# from django.conf import settings
from django.conf import settings
class SiteName(models.TextChoices):
@ -229,6 +229,10 @@ class Item(SoftDeleteMixin, PolymorphicModel):
def url(self):
return f'/{self.url_path}/{self.uuid}/'
@property
def absolute_url(self):
return settings.APP_WEBSITE + self.url
@property
def api_url(self):
return '/api' + self.url

View file

@ -96,7 +96,7 @@
{% endif %}
</div>
{% if item.last_editor and item.last_editor.preference.show_last_edit or user.is_staff %}
{% if item.last_editor and item.last_editor.preference.show_last_edit %}
<div>{% trans '最近编辑者:' %}<a href="{% url 'users:home' item.last_editor.mastodon_username %}">{{ item.last_editor | default:"" }}</a></div>
{% endif %}

View file

@ -33,7 +33,8 @@
{% include "partial/_common_libs.html" with jquery=1 %}
<script src="{% static 'lib/js/rating-star.js' %}"></script>
<script src="{% static 'js/detail.js' %}"></script>
<script src="{% static 'lib/js/tag-input.js' %}"></script>
<link href="{% static 'lib/css/tag-input.css' %}" type="text/css" media="all" rel="stylesheet">
</head>
<body>
@ -68,7 +69,7 @@
<div class="entity-detail__fields">
<div class="entity-detail__rating">
{% if item.rating %}
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:"0" }}"></span>
<span class="entity-detail__rating-star rating-star" data-rating-score="{{ item.rating | floatformat:'0' }}"></span>
<span class="entity-detail__rating-score"> {{ item.rating }} </span>
<small>({{ item.rating_count }}人评分)</small>
{% else %}
@ -166,13 +167,13 @@
<div class="mark-panel">
<span class="mark-panel__status">{% trans '我' %}{% trans mark.shelf_label %}</span>
{% if mark.rating %}
<span class="mark-panel__rating-star rating-star" data-rating-score="{{ mark.rating | floatformat:"0" }}"></span>
<span class="mark-panel__rating-star rating-star" data-rating-score="{{ mark.rating | floatformat:'0' }}"></span>
{% endif %}
{% if mark.visibility > 0 %}
<span class="icon-lock"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17,8.48h-.73V6.27a6.27,6.27,0,1,0-12.53,0V8.48H3a.67.67,0,0,0-.67.67V19.33A.67.67,0,0,0,3,20H17a.67.67,0,0,0,.67-.67V9.15A.67.67,0,0,0,17,8.48ZM6.42,6.27h0a3.57,3.57,0,0,1,7.14,0h0V8.48H6.42Z"/></svg></span>
{% endif %}
<span class="mark-panel__actions">
<a href="" class="edit">{% trans '修改' %}</a>
<a href="#" hx-get="{% url 'journal:mark' item.uuid %}" class="edit" hx-target="body" hx-swap="beforeend">{% trans '修改' %}</a>
<form action="{% url 'books:delete_mark' mark.id %}" method="post">
{% csrf_token %}
<a href="" class="delete">{% trans '删除' %}</a>
@ -180,7 +181,13 @@
</span>
<div class="mark-panel__clear"></div>
<div class="mark-panel__time">{{ mark.created_time }}</div>
<div class="mark-panel__time">
{% if mark.metadata.shared_link %}
<a href="{{ mark.metadata.shared_link }}">{{ mark.created_time }}</a>
{% else %}
{{ mark.created_time }}
{% endif %}
</div>
{% if mark.text %}
<p class="mark-panel__text">{{ mark.text }}</p>
@ -245,23 +252,25 @@
{% endblock %}
{% block sidebar_collection %}
{% if collection_list %}
<div class="aside-section-wrapper">
<div class="action-panel">
<div class="action-panel__label">{% trans '相关收藏单' %}</div>
<div >
{% if collection_list %}
{% for c in collection_list %}
<p>
<a href="{% url 'collection:retrieve' c.id %}">{{ c.title }}</a>
</p>
{% endfor %}
{% endif %}
{% if request.user.is_authenticated %}
<div class="action-panel__button-group action-panel__button-group--center">
<button class="action-panel__button add-to-list" hx-get="{% url 'collection:add_to_list' 'book' item.id %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
<button class="action-panel__button add-to-list" hx-get="{% url 'journal:add_to_collection' item.uuid %}" hx-target="body" hx-swap="beforeend">{% trans '添加到收藏单' %}</button>
</div>
{% endif %}
</div>
</div>
</div>
{% endif %}
{% endblock %}
</div>
</div>
@ -269,97 +278,44 @@
</div>
{% include "partial/_footer.html" %}
</div>
<script>
// readonly star rating of detail display section
let ratingLabels = $("#main .rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
});
});
// readonly star rating at aside section
ratingLabels = $("#aside .rating-star");
$(ratingLabels).each( function(index, value) {
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
starSize: 15,
});
});
// hide long text
$(".entity-desc__content").each(function() {
let copy = $(this).clone()
.addClass('entity-desc__content--folded')
.css("visibility", "hidden");
$(this).after(copy);
if ($(this).height() > copy.height()) {
$(this).addClass('entity-desc__content--folded');
$(this).siblings(".entity-desc__unfold-button").removeClass("entity-desc__unfold-button--hidden");
}
copy.remove();
});
<div id="modals">
<div class="mark-modal modal">
<div class="mark-modal__head">
{% if not mark %}
<style>
.mark-modal__title::after {
content: "{% trans item.demonstrative %}";
}
</style>
<span class="mark-modal__title"></span>
{% else %}
<span class="mark-modal__title">{% trans '我的标记' %}</span>
{% endif %}
<span class="mark-modal__close-button modal-close">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</span>
</span>
</div>
<div class="mark-modal__body">
<form action="{% url 'books:create_update_mark' %}" method="post">
{{ mark_form.media }}
{% csrf_token %}
{{ mark_form.id }}
{{ mark_form.book }}
{% if mark.rating %}
{% endif %}
<div class="mark-modal__rating-star rating-star-edit"></div>
{{ mark_form.rating }}
<div id="statusSelection" class="mark-modal__status-radio" {% if not mark %}hidden{% endif %}>
{{ mark_form.status }}
</div>
<div class="mark-modal__clear"></div>
{{ mark_form.text }}
<div class="mark-modal__tag">
<label>{{ mark_form.tags.label }}</label>
{{ mark_form.tags }}
</div>
<div class="mark-modal__option">
<div class="mark-modal__visibility-radio">
<span>{{ mark_form.visibility.label }}:
{{ mark_form.visibility }}</span>
</div>
<div class="mark-modal__share-checkbox">
{{ mark_form.share_to_mastodon }}{{ mark_form.share_to_mastodon.label }}
</div>
</div>
<div class="mark-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '提交' %}">
</div>
</form>
</div>
</div>
<div class="confirm-modal modal">
<div class="confirm-modal__head">
<span class="confirm-modal__title">{% trans '确定要删除你的标记吗?' %}</span>
<span class="confirm-modal__close-button modal-close">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</span>
</span>
</div>
<div class="confirm-modal__body">
<div class="confirm-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '确认' %}">
</div>
</div>
</div>
</div>
<div class="bg-mask"></div>
<script>
</script>
// expand hidden long text
$(".entity-desc__unfold-button a").on('click', function() {
$(this).parent().siblings(".entity-desc__content").removeClass('entity-desc__content--folded');
$(this).parent(".entity-desc__unfold-button").remove();
});
</script>
</body>
</html>

View file

@ -11,9 +11,6 @@ from django.core.paginator import Paginator
from mastodon import mastodon_request_included
from mastodon.models import MastodonApplication
from mastodon.api import share_mark, share_review
from common.utils import PageLinksGenerator
from common.views import PAGE_LINK_NUMBER, jump_or_scrape, go_relogin
from common.models import SourceSiteEnum
from .models import *
# from .forms import *
# from .forms import BookMarkStatusTranslator
@ -22,6 +19,7 @@ from collection.models import CollectionItem
from common.scraper import get_scraper_by_url, get_normalized_url
from django.utils.baseconv import base62
from journal.models import Mark
from journal.models import query_visible
_logger = logging.getLogger(__name__)
@ -48,65 +46,9 @@ def retrieve(request, item_path, item_uid):
mark_form = None
if request.user.is_authenticated:
mark = Mark(request.user, item)
_logger.info(mark.rating)
review = mark.review
# # retreive tags
# book_tag_list = book.book_tags.values('content').annotate(
# tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER]
# # retrieve user mark and initialize mark form
# try:
# if request.user.is_authenticated:
# mark = BookMark.objects.get(owner=request.user, book=book)
# except ObjectDoesNotExist:
# mark = None
# if mark:
# mark_tags = mark.bookmark_tags.all()
# mark.get_status_display = BookMarkStatusTranslator(mark.status)
# mark_form = BookMarkForm(instance=mark, initial={
# 'tags': mark_tags
# })
# else:
# mark_form = BookMarkForm(initial={
# 'book': book,
# 'visibility': request.user.get_preference().default_visibility if request.user.is_authenticated else 0,
# 'tags': mark_tags
# })
# # retrieve user review
# try:
# if request.user.is_authenticated:
# review = BookReview.objects.get(owner=request.user, book=book)
# except ObjectDoesNotExist:
# review = None
# # retrieve other related reviews and marks
# if request.user.is_anonymous:
# # hide all marks and reviews for anonymous user
# mark_list = None
# review_list = None
# mark_list_more = None
# review_list_more = None
# else:
# mark_list = BookMark.get_available_for_identicals(book, request.user)
# review_list = BookReview.get_available_for_identicals(book, request.user)
# mark_list_more = True if len(mark_list) > MARK_NUMBER else False
# mark_list = mark_list[:MARK_NUMBER]
# for m in mark_list:
# m.get_status_display = BookMarkStatusTranslator(m.status)
# review_list_more = True if len(
# review_list) > REVIEW_NUMBER else False
# review_list = review_list[:REVIEW_NUMBER]
# all_collections = CollectionItem.objects.filter(book=book).annotate(num_marks=Count('collection__collection_marks')).order_by('-num_marks')[:20]
# collection_list = filter(lambda c: c.is_visible_to(request.user), map(lambda i: i.collection, all_collections))
# def strip_html_tags(text):
# import re
# regex = re.compile('<.*?>')
# return re.sub(regex, '', text)
# for r in review_list:
# r.content = strip_html_tags(r.content)
collection_list = item.collections.all().filter(query_visible(request.user)).annotate(like_counts=Count('likes')).order_by('-like_counts')
return render(request, item.class_name + '.html', {
'item': item,

View file

@ -19,6 +19,11 @@ import math
import uuid
from catalog.common.utils import DEFAULT_ITEM_COVER, item_cover_path
from django.utils.baseconv import base62
from django.db.models import Q
def query_visible(user):
return Q(visibility=0) | Q(owner_id__in=user.following, visibility__lt=2) | Q(owner_id=user.id)
class Piece(PolymorphicModel, UserOwnedObjectMixin):
@ -276,14 +281,16 @@ ShelfTypeNames = [
[ItemCategory.Game, ShelfType.WISHLIST, _('想玩')],
[ItemCategory.Game, ShelfType.PROGRESS, _('在玩')],
[ItemCategory.Game, ShelfType.COMPLETE, _('玩过')],
[ItemCategory.Collection, ShelfType.WISHLIST, _('关注')],
# TODO add more combinations
]
class ShelfMember(ListMember):
parent = models.ForeignKey('Shelf', related_name='members', on_delete=models.CASCADE)
@cached_property
def mark(self):
return Mark(self.owner, self.item)
class Shelf(List):
class Meta:
@ -487,6 +494,11 @@ class TagManager:
tag = Tag.objects.filter(owner=user, title=title).first()
tag.remove_item(item)
@staticmethod
def get_item_tags_by_user(item, user):
current_titles = [m.parent.title for m in TagMember.objects.filter(owner=user, item=item)]
return current_titles
@staticmethod
def add_tag_by_user(item, tag_title, user, default_visibility=0):
title = Tag.cleanup_title(tag_title)
@ -535,6 +547,10 @@ class Mark:
def id(self):
return self.shelfmember.id if self.shelfmember else None
@property
def shelf(self):
return self.shelfmember.parent if self.shelfmember else None
@property
def shelf_type(self):
return self.shelfmember.parent.shelf_type if self.shelfmember else None
@ -575,7 +591,8 @@ class Mark:
def review(self):
return Review.objects.filter(owner=self.owner, item=self.item).first()
def update(self, shelf_type, comment_text, rating_grade, visibility, metadata=None, created_time=None):
def update(self, shelf_type, comment_text, rating_grade, visibility, metadata=None, created_time=None, share_to_mastodon=False):
share = share_to_mastodon and shelf_type is not None and (shelf_type != self.shelf_type or comment_text != self.text or rating_grade != self.rating)
if shelf_type != self.shelf_type or visibility != self.visibility:
self.shelfmember = self.owner.shelf_manager.move_item(self.item, shelf_type, visibility=visibility, metadata=metadata)
if self.shelfmember and created_time:
@ -586,3 +603,17 @@ class Mark:
if rating_grade != self.rating or visibility != self.visibility:
Rating.rate_item_by_user(self.item, self.owner, rating_grade, visibility)
self.rating = rating_grade
if share:
# this is a bit hacky but let's keep it until move to implement ActivityPub,
# by then, we'll just change this to boost
from mastodon.api import share_mark
self.shared_link = self.shelfmember.metadata.get('shared_link') if self.shelfmember.metadata else None
self.translated_status = self.shelf_label
self.save = lambda **args: None
if not share_mark(self):
raise ValueError("sharing failed")
if not self.shelfmember.metadata:
self.shelfmember.metadata = {}
if self.shelfmember.metadata.get('shared_link') != self.shared_link:
self.shelfmember.metadata['shared_link'] = self.shared_link
self.shelfmember.save()

View file

@ -0,0 +1,45 @@
{% load static %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load highlight %}
{% load thumb %}
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
<div class="modal-underlay" _="on click trigger closeModal"></div>
<div class="modal-content">
<div class="add-to-list-modal__head">
<span class="add-to-list-modal__title">{% trans '添加到收藏单' %}</span>
<span class="add-to-list-modal__close-button modal-close" _="on click trigger closeModal">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</span>
</span>
</div>
<div class="add-to-list-modal__body">
<form action="{% url 'journal:add_to_collection' item.uuid %}" method="post">
{% csrf_token %}
<select name="collection_id">
{% for collection in collections %}
<option value="{{ collection.id }}">{{ collection.title }}{% if collection.visibility > 0 %}🔒{% endif %}</option>
{% endfor %}
<option value="0">新建收藏单</option>
</select>
<div>
<textarea type="text" name="comment" placeholder="条目备注"></textarea>
</div>
<div class="add-to-list-modal__confirm-button">
<input type="submit" class="button float-right" value="{% trans '提交' %}">
</div>
</form>
</div>
</div>
</div>

128
journal/templates/mark.html Normal file
View file

@ -0,0 +1,128 @@
{% load static %}
{% load i18n %}
{% load l10n %}
{% load humanize %}
{% load admin_url %}
{% load mastodon %}
{% load oauth_token %}
{% load truncate %}
{% load highlight %}
{% load thumb %}
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
<div class="modal-underlay" _="on click trigger closeModal"></div>
<div class="modal-content">
<div class="add-to-list-modal__head">
<span class="add-to-list-modal__title">{% trans '标记' %} {{ item.title }}</span>
<span class="add-to-list-modal__close-button modal-close" _="on click trigger closeModal">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<polygon
points="20 2.61 17.39 0 10 7.39 2.61 0 0 2.61 7.39 10 0 17.39 2.61 20 10 12.61 17.39 20 20 17.39 12.61 10 20 2.61">
</polygon>
</svg>
</span>
</span>
</div>
<div class="add-to-list-modal__body">
<form action="{% url 'journal:mark' item.uuid %}" method="post">
{% csrf_token %}
<div id="statusSelection" class="mark-modal__status-radio float-right">
<ul id="id_status">
{% for k, v in shelf_types %}
<li><label for="id_status_{{ k }}"><input type="radio" name="status" value="{{ k }}" required="" id="id_status_{{ k }}" {% if mark.shelf_type == k %}checked=""{% endif %}> {{ v }}</label></li>
{% endfor %}
</ul>
</div>
<div class="mark-modal__rating-star rating-star-edit"></div>
<input type="hidden" name="rating" id="id_rating" value="{{ mark.rating }}">
<div class="mark-modal__clear"></div>
<textarea name="text" cols="40" rows="10" placeholder="超过360字部分实例可能无法显示" maxlength="360" id="id_text">{{ mark.text }}</textarea>
<div class="mark-modal__tag">
<label>标签</label>
<div class="tag-input">
<input name="tags" type="text" placeholder="回车增加标签" id="id_tags" value="">
</div>
</div>
<div class="mark-modal__share-checkbox float-right">
<input type="checkbox" name="share_to_mastodon" id="id_share_to_mastodon" value="1" checked>分享到联邦网络
</div>
<div class="mark-modal__option">
<div class="mark-modal__visibility-radio">
<span>可见性:
<ul id="id_visibility">
<li><label for="id_visibility_0"><input type="radio" name="visibility" value="0" required="" id="id_visibility_0" {% if mark.visibility == 0 %}checked{% endif %}> 公开</label> </li>
<li><label for="id_visibility_1"><input type="radio" name="visibility" value="1" required="" id="id_visibility_1" {% if mark.visibility == 1 %}checked{% endif %}> 仅关注者</label> </li>
<li><label for="id_visibility_2"><input type="radio" name="visibility" value="2" required="" id="id_visibility_2" {% if mark.visibility == 2 %}checked{% endif %}> 仅自己</label> </li>
</ul>
</span>
</div>
</div>
<div class="mark-modal__confirm-button">
<input type="submit" class="button float-right" value="保存">
</div>
</form>
</div>
<script>
(function(){
new inputTags({
container: document.getElementsByClassName("tag-input")[0],
tags : "{{ tags }}".split(","),
allowDuplicateTags : false,
duplicateTime: 300,
onTagRemove : function (tag) {},
});
// editable rating star in modal
ratingLabels = $("#modal .rating-star-edit");
$(ratingLabels).each( function(index, value) {
let ratingScore = $("input[type='hidden'][name='rating']").val() / 2;
let label = $(this);
label.starRating({
initialRating: ratingScore,
starSize: 20,
onHover: function(currentIndex, currentRating, $el){
$("input[type='hidden'][name='rating']").val(currentIndex);
},
onLeave: function(currentIndex, currentRating, $el){
$("input[type='hidden'][name='rating']").val(currentRating * 2);
}
});
});
// hide rating star when select wish
const WISH_CODE = "wishlist";
if ($("#statusSelection input[type='radio']:checked").val() == WISH_CODE) {
$("#model .rating-star-edit").hide();
}
$("#statusSelection input[type='radio']").on('click', function() {
if ($(this).val() == WISH_CODE) {
$("#model .rating-star-edit").hide();
} else {
$("#model .rating-star-edit").show();
}
});
// show confirm modal
$("#model a.delete").on('click', function(e) {
e.preventDefault();
$(".confirm-modal").show();
$(".bg-mask").show();
});
// confirm modal
$(".confirm-modal input[type='submit']").on('click', function(e) {
e.preventDefault();
$("#model form").submit();
});
})();
</script>
</div>

View file

@ -6,4 +6,6 @@ app_name = 'journal'
urlpatterns = [
path('wish/<str:item_uuid>', wish, name='wish'),
path('like/<str:piece_uuid>', like, name='like'),
path('mark/<str:item_uuid>', mark, name='mark'),
path('add_to_collection/<str:item_uuid>', add_to_collection, name='add_to_collection'),
]

View file

@ -19,6 +19,7 @@ from management.models import Announcement
from django.utils.baseconv import base62
_logger = logging.getLogger(__name__)
PAGE_SIZE = 10
@ -44,3 +45,61 @@ def like(request, piece_uuid):
return HttpResponse("✔️")
else:
return HttpResponseBadRequest("invalid request")
@login_required
def add_to_collection(request, item_uuid):
item = get_object_or_404(Item, uid=base62.decode(item_uuid))
if request.method == 'GET':
collections = Collection.objects.filter(owner=request.user)
return render(
request,
'add_to_collection.html',
{
'item': item,
'collections': collections,
}
)
else:
cid = int(request.POST.get('collection_id', default=0))
if not cid:
cid = Collection.objects.create(owner=request.user, title=f'{request.user.username}的收藏单').id
collection = Collection.objects.get(owner=request.user, id=cid)
collection.append_item(item, metadata={'comment': request.POST.get('comment')})
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
def go_relogin(request):
return render(request, 'common/error.html', {
'url': reverse("users:connect") + '?domain=' + request.user.mastodon_site,
'msg': _("信息已保存,但是未能分享到联邦网络"),
'secondary_msg': _("可能是你在联邦网络(Mastodon/Pleroma/...)的登录状态过期了,正在跳转到联邦网络重新登录😼")})
@login_required
def mark(request, item_uuid):
item = get_object_or_404(Item, uid=base62.decode(item_uuid))
mark = Mark(request.user, item)
if request.method == 'GET':
tags = TagManager.get_item_tags_by_user(item, request.user)
shelf_types = [(n[1], n[2]) for n in iter(ShelfTypeNames) if n[0] == item.category]
return render(request, 'mark.html', {
'item': item,
'mark': mark,
'tags': ','.join(tags),
'shelf_types': shelf_types,
})
elif request.method == 'POST':
visibility = int(request.POST.get('visibility', default=0))
rating = int(request.POST.get('rating', default=0))
status = ShelfType(request.POST.get('status'))
text = request.POST.get('text')
tags = request.POST.get('tags')
tags = tags.split(',') if tags else []
share_to_mastodon = bool(request.POST.get('share_to_mastodon', default=False))
TagManager.tag_item_by_user(item, request.user, tags, visibility)
try:
mark.update(status, text, rating, visibility, share_to_mastodon=share_to_mastodon)
except Exception:
go_relogin(request)
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

View file

@ -108,7 +108,6 @@ class DefaultActivityProcessor:
'template': self.template,
'action_object': self.action_object,
}
print(params)
LocalActivity.objects.create(**params)
def updated(self):

View file

@ -45,17 +45,14 @@
{% endfor %}
</div>
<p class="entity-list__entity-brief">
{% if activity.review %}
{% if activity.action_object.review %}
<a href="{{ activity.review.url }}">{{ activity.review.title }}</a>
{% endif %}
{% if activity.mark %}
{% if activity.mark.rating %}
<span class="entity-marks__rating-star rating-star" data-rating-score="{{ activity.mark.rating | floatformat:"0" }}" style=""></span>
{% endif %}
{% if activity.mark.text %}
<p class="entity-marks__mark-content">{{ activity.mark.text }}</p>
{% if activity.action_object.mark.rating %}
<span class="entity-marks__rating-star rating-star" data-rating-score="{{ activity.action_object.mark.rating }}" style=""></span>
{% endif %}
{% if activity.action_object.mark.text %}
<p class="entity-marks__mark-content">{{ activity.action_object.mark.text }}</p>
{% endif %}
</p>
</div>

View file

@ -78,3 +78,16 @@ hx-swap="outerHTML">
{% empty %}
<div>{% trans '目前没有更多内容了' %}</div>
{% endfor %}
<script>
// readonly star rating at aside section
ratingLabels = $(".rating-star");
$(ratingLabels).each( function(index, value) {
console.log($(this).data("rating-score"))
let ratingScore = $(this).data("rating-score") / 2;
$(this).starRating({
initialRating: ratingScore,
readOnly: true,
starSize: 15,
});
});
</script>