mirror of
https://github.com/daniviga/django-ram.git
synced 2025-12-26 07:18:32 +01:00
Fully implement UI for magazines
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
# Generated by Django 6.0 on 2025-12-10 20:59
|
||||
|
||||
import bookshelf.models
|
||||
import ram.utils
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookshelf", "0025_magazine_magazineissue"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="basebook",
|
||||
name="language",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("af", "Afrikaans"),
|
||||
("sq", "Albanian"),
|
||||
("ar-dz", "Algerian Arabic"),
|
||||
("ar", "Arabic"),
|
||||
("es-ar", "Argentinian Spanish"),
|
||||
("hy", "Armenian"),
|
||||
("ast", "Asturian"),
|
||||
("en-au", "Australian English"),
|
||||
("az", "Azerbaijani"),
|
||||
("eu", "Basque"),
|
||||
("be", "Belarusian"),
|
||||
("bn", "Bengali"),
|
||||
("bs", "Bosnian"),
|
||||
("pt-br", "Brazilian Portuguese"),
|
||||
("br", "Breton"),
|
||||
("en-gb", "British English"),
|
||||
("bg", "Bulgarian"),
|
||||
("my", "Burmese"),
|
||||
("ca", "Catalan"),
|
||||
("ckb", "Central Kurdish (Sorani)"),
|
||||
("es-co", "Colombian Spanish"),
|
||||
("hr", "Croatian"),
|
||||
("cs", "Czech"),
|
||||
("da", "Danish"),
|
||||
("nl", "Dutch"),
|
||||
("en", "English"),
|
||||
("eo", "Esperanto"),
|
||||
("et", "Estonian"),
|
||||
("fi", "Finnish"),
|
||||
("fr", "French"),
|
||||
("fy", "Frisian"),
|
||||
("gl", "Galician"),
|
||||
("ka", "Georgian"),
|
||||
("de", "German"),
|
||||
("el", "Greek"),
|
||||
("ht", "Haitian Creole"),
|
||||
("he", "Hebrew"),
|
||||
("hi", "Hindi"),
|
||||
("hu", "Hungarian"),
|
||||
("is", "Icelandic"),
|
||||
("io", "Ido"),
|
||||
("ig", "Igbo"),
|
||||
("id", "Indonesian"),
|
||||
("ia", "Interlingua"),
|
||||
("ga", "Irish"),
|
||||
("it", "Italian"),
|
||||
("ja", "Japanese"),
|
||||
("kab", "Kabyle"),
|
||||
("kn", "Kannada"),
|
||||
("kk", "Kazakh"),
|
||||
("km", "Khmer"),
|
||||
("ko", "Korean"),
|
||||
("ky", "Kyrgyz"),
|
||||
("lv", "Latvian"),
|
||||
("lt", "Lithuanian"),
|
||||
("dsb", "Lower Sorbian"),
|
||||
("lb", "Luxembourgish"),
|
||||
("mk", "Macedonian"),
|
||||
("ms", "Malay"),
|
||||
("ml", "Malayalam"),
|
||||
("mr", "Marathi"),
|
||||
("es-mx", "Mexican Spanish"),
|
||||
("mn", "Mongolian"),
|
||||
("ne", "Nepali"),
|
||||
("es-ni", "Nicaraguan Spanish"),
|
||||
("nb", "Norwegian Bokmål"),
|
||||
("nn", "Norwegian Nynorsk"),
|
||||
("os", "Ossetic"),
|
||||
("fa", "Persian"),
|
||||
("pl", "Polish"),
|
||||
("pt", "Portuguese"),
|
||||
("pa", "Punjabi"),
|
||||
("ro", "Romanian"),
|
||||
("ru", "Russian"),
|
||||
("gd", "Scottish Gaelic"),
|
||||
("sr", "Serbian"),
|
||||
("sr-latn", "Serbian Latin"),
|
||||
("zh-hans", "Simplified Chinese"),
|
||||
("sk", "Slovak"),
|
||||
("sl", "Slovenian"),
|
||||
("es", "Spanish"),
|
||||
("sw", "Swahili"),
|
||||
("sv", "Swedish"),
|
||||
("tg", "Tajik"),
|
||||
("ta", "Tamil"),
|
||||
("tt", "Tatar"),
|
||||
("te", "Telugu"),
|
||||
("th", "Thai"),
|
||||
("zh-hant", "Traditional Chinese"),
|
||||
("tr", "Turkish"),
|
||||
("tk", "Turkmen"),
|
||||
("udm", "Udmurt"),
|
||||
("uk", "Ukrainian"),
|
||||
("hsb", "Upper Sorbian"),
|
||||
("ur", "Urdu"),
|
||||
("ug", "Uyghur"),
|
||||
("uz", "Uzbek"),
|
||||
("es-ve", "Venezuelan Spanish"),
|
||||
("vi", "Vietnamese"),
|
||||
("cy", "Welsh"),
|
||||
],
|
||||
default="en",
|
||||
max_length=7,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="magazine",
|
||||
name="image",
|
||||
field=models.ImageField(
|
||||
blank=True,
|
||||
storage=ram.utils.DeduplicatedStorage,
|
||||
upload_to=bookshelf.models.magazine_image_upload,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="magazine",
|
||||
name="language",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("af", "Afrikaans"),
|
||||
("sq", "Albanian"),
|
||||
("ar-dz", "Algerian Arabic"),
|
||||
("ar", "Arabic"),
|
||||
("es-ar", "Argentinian Spanish"),
|
||||
("hy", "Armenian"),
|
||||
("ast", "Asturian"),
|
||||
("en-au", "Australian English"),
|
||||
("az", "Azerbaijani"),
|
||||
("eu", "Basque"),
|
||||
("be", "Belarusian"),
|
||||
("bn", "Bengali"),
|
||||
("bs", "Bosnian"),
|
||||
("pt-br", "Brazilian Portuguese"),
|
||||
("br", "Breton"),
|
||||
("en-gb", "British English"),
|
||||
("bg", "Bulgarian"),
|
||||
("my", "Burmese"),
|
||||
("ca", "Catalan"),
|
||||
("ckb", "Central Kurdish (Sorani)"),
|
||||
("es-co", "Colombian Spanish"),
|
||||
("hr", "Croatian"),
|
||||
("cs", "Czech"),
|
||||
("da", "Danish"),
|
||||
("nl", "Dutch"),
|
||||
("en", "English"),
|
||||
("eo", "Esperanto"),
|
||||
("et", "Estonian"),
|
||||
("fi", "Finnish"),
|
||||
("fr", "French"),
|
||||
("fy", "Frisian"),
|
||||
("gl", "Galician"),
|
||||
("ka", "Georgian"),
|
||||
("de", "German"),
|
||||
("el", "Greek"),
|
||||
("ht", "Haitian Creole"),
|
||||
("he", "Hebrew"),
|
||||
("hi", "Hindi"),
|
||||
("hu", "Hungarian"),
|
||||
("is", "Icelandic"),
|
||||
("io", "Ido"),
|
||||
("ig", "Igbo"),
|
||||
("id", "Indonesian"),
|
||||
("ia", "Interlingua"),
|
||||
("ga", "Irish"),
|
||||
("it", "Italian"),
|
||||
("ja", "Japanese"),
|
||||
("kab", "Kabyle"),
|
||||
("kn", "Kannada"),
|
||||
("kk", "Kazakh"),
|
||||
("km", "Khmer"),
|
||||
("ko", "Korean"),
|
||||
("ky", "Kyrgyz"),
|
||||
("lv", "Latvian"),
|
||||
("lt", "Lithuanian"),
|
||||
("dsb", "Lower Sorbian"),
|
||||
("lb", "Luxembourgish"),
|
||||
("mk", "Macedonian"),
|
||||
("ms", "Malay"),
|
||||
("ml", "Malayalam"),
|
||||
("mr", "Marathi"),
|
||||
("es-mx", "Mexican Spanish"),
|
||||
("mn", "Mongolian"),
|
||||
("ne", "Nepali"),
|
||||
("es-ni", "Nicaraguan Spanish"),
|
||||
("nb", "Norwegian Bokmål"),
|
||||
("nn", "Norwegian Nynorsk"),
|
||||
("os", "Ossetic"),
|
||||
("fa", "Persian"),
|
||||
("pl", "Polish"),
|
||||
("pt", "Portuguese"),
|
||||
("pa", "Punjabi"),
|
||||
("ro", "Romanian"),
|
||||
("ru", "Russian"),
|
||||
("gd", "Scottish Gaelic"),
|
||||
("sr", "Serbian"),
|
||||
("sr-latn", "Serbian Latin"),
|
||||
("zh-hans", "Simplified Chinese"),
|
||||
("sk", "Slovak"),
|
||||
("sl", "Slovenian"),
|
||||
("es", "Spanish"),
|
||||
("sw", "Swahili"),
|
||||
("sv", "Swedish"),
|
||||
("tg", "Tajik"),
|
||||
("ta", "Tamil"),
|
||||
("tt", "Tatar"),
|
||||
("te", "Telugu"),
|
||||
("th", "Thai"),
|
||||
("zh-hant", "Traditional Chinese"),
|
||||
("tr", "Turkish"),
|
||||
("tk", "Turkmen"),
|
||||
("udm", "Udmurt"),
|
||||
("uk", "Ukrainian"),
|
||||
("hsb", "Upper Sorbian"),
|
||||
("ur", "Urdu"),
|
||||
("ug", "Uyghur"),
|
||||
("uz", "Uzbek"),
|
||||
("es-ve", "Venezuelan Spanish"),
|
||||
("vi", "Vietnamese"),
|
||||
("cy", "Welsh"),
|
||||
],
|
||||
default="en",
|
||||
max_length=7,
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -43,8 +43,8 @@ class BaseBook(BaseModel):
|
||||
ISBN = models.CharField(max_length=17, blank=True) # 13 + dashes
|
||||
language = models.CharField(
|
||||
max_length=7,
|
||||
choices=settings.LANGUAGES,
|
||||
default='en'
|
||||
choices=sorted(settings.LANGUAGES, key=lambda s: s[1]),
|
||||
default="en",
|
||||
)
|
||||
number_of_pages = models.SmallIntegerField(null=True, blank=True)
|
||||
publication_year = models.SmallIntegerField(null=True, blank=True)
|
||||
@@ -177,7 +177,7 @@ class Magazine(BaseModel):
|
||||
)
|
||||
language = models.CharField(
|
||||
max_length=7,
|
||||
choices=settings.LANGUAGES,
|
||||
choices=sorted(settings.LANGUAGES, key=lambda s: s[1]),
|
||||
default='en'
|
||||
)
|
||||
tags = models.ManyToManyField(
|
||||
@@ -234,6 +234,10 @@ class MagazineIssue(BaseBook):
|
||||
def preview(self):
|
||||
return self.image.first().image_thumbnail(100)
|
||||
|
||||
@property
|
||||
def publisher(self):
|
||||
return self.magazine.publisher
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
"issue",
|
||||
|
||||
@@ -89,7 +89,30 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Publisher</th>
|
||||
<td>{{ book.publisher }}</td>
|
||||
<td>
|
||||
<img src="{{ book.publisher.country.flag }}" alt="{{ book.publisher.country }}"> {{ book.publisher }}
|
||||
{% if book.publisher.website %} <a href="{{ book.publisher.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% elif type == "magazineissue" %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Magazine</th>
|
||||
<td><a href="{% url 'magazine' book.magazine.pk %}">{{ book.magazine }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Publisher</th>
|
||||
<td>
|
||||
<img src="{{ book.publisher.country.flag }}" alt="{{ book.publisher.country }}"> {{ book.publisher }}
|
||||
{% if book.publisher.website %} <a href="{{ book.publisher.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Issue</th>
|
||||
<td>{{ book.issue_number }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Date</th>
|
||||
<td>{{ book.publication_year|default:"-" }} / {{ book.publication_month|default:"-" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
@@ -104,10 +127,12 @@
|
||||
<th scope="row">Number of pages</th>
|
||||
<td>{{ book.number_of_pages|default:"-" }}</td>
|
||||
</tr>
|
||||
{% if type == "boook" or type == "catalog" %}
|
||||
<tr>
|
||||
<th scope="row">Publication year</th>
|
||||
<td>{{ book.publication_year|default:"-" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if book.description %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Description</th>
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
{% if catalogs_menu %}
|
||||
<li><a class="dropdown-item" href="{% url 'catalogs' %}">Catalogs</a></li>
|
||||
{% endif %}
|
||||
{% if magazines_menu %}
|
||||
<li><a class="dropdown-item" href="{% url 'magazines' %}">Magazines</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{% include "cards/consist.html" %}
|
||||
{% elif d.type == "manufacturer" %}
|
||||
{% include "cards/manufacturer.html" %}
|
||||
{% elif d.type == "magazine" or d.type == "issue" %}
|
||||
{% elif d.type == "magazine" or d.type == "magazineissue" %}
|
||||
{% include "cards/magazine.html" %}
|
||||
{% elif d.type == "book" or d.type == "catalog" %}
|
||||
{% include "cards/book.html" %}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{% load static %}
|
||||
|
||||
<div class="col">
|
||||
<div class="card shadow-sm">
|
||||
{% if d.type == "magazine" %}
|
||||
@@ -15,9 +14,7 @@
|
||||
<img class="card-img-top d-none d-sm-block" src="{% static DEFAULT_CARD_IMAGE %}" alt="{{ d.item }}">
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if d.type == "issue" %}
|
||||
{% elif d.type == "magazineissue" %}
|
||||
<a href="{{ d.item.get_absolute_url }}">
|
||||
{% if d.item.image.exists %}
|
||||
<img class="card-img-top" src="{{ d.item.image.first.image.url }}" alt="{{ d.item }}">
|
||||
@@ -54,10 +51,33 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-group-divider">
|
||||
{% if d.type == "magazineissue" %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Magazine</th>
|
||||
<td>{{ d.item.magazine }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Publisher</th>
|
||||
<td><img src="{{ d.item.publisher.country.flag }}" alt="{{ d.item.publisher.country }}"> {{ d.item.publisher }}</td>
|
||||
<td>
|
||||
<img src="{{ d.item.publisher.country.flag }}" alt="{{ d.item.publisher.country }}"> {{ d.item.publisher }}
|
||||
{% if d.item.publisher.website %} <a href="{{ d.item.publisher.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% if d.type == "magazineissue" %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Issue</th>
|
||||
<td>{{ d.item.issue_number }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Date</th>
|
||||
<td>{{ d.item.publication_year|default:"-" }} / {{ d.item.publication_month|default:"-" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Pages</th>
|
||||
<td>{{ d.item.number_of_pages|default:"-" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Language</th>
|
||||
<td>{{ d.item.get_language_display }}</td>
|
||||
@@ -65,8 +85,12 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="d-grid gap-2 mb-1 d-md-block">
|
||||
{% if d.type == "magazine" %}
|
||||
<a class="btn btn-sm btn-outline-primary{% if d.item.issues == 0 %} disabled{% endif %}" href="{{ d.item.get_absolute_url }}">Show {{ d.item.issues }} issue{{ d.item.issues|pluralize }}</a>
|
||||
{% else %}
|
||||
<a class="btn btn-sm btn-outline-primary" href="{{ d.item.get_absolute_url }}">Show all data</a>
|
||||
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:bookshelf_magazine_change' d.item.pk %}">Edit</a>{% endif %}
|
||||
{% endif %}
|
||||
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:bookshelf_magazineissue_change' d.item.pk %}">Edit</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "cards.html" %}
|
||||
|
||||
{% block header %}
|
||||
{{ block.super }}
|
||||
{% if magazine.tags.all %}
|
||||
<p><small>Tags:</small>
|
||||
{% for t in magazine.tags.all %}<a href="{% url 'filtered' _filter="tag" search=t.slug %}" class="badge rounded-pill bg-primary">
|
||||
@@ -87,13 +87,19 @@
|
||||
</thead>
|
||||
<tbody class="table-group-divider">
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Company</th>
|
||||
<th class="w-33" scope="row">Name</th>
|
||||
<td>{{ magazine }} </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="w-33" scope="row">Publisher</th>
|
||||
<td>
|
||||
<img src="{{ magazine.publisher.country.flag }}" alt="{{ magazine.publisher.country }}"> {{ magazine.publisher }}
|
||||
{% if magazine.publisher.website %} <a href="{{ magazine.publisher.website }}" target="_blank"><i class="bi bi-box-arrow-up-right"></i></a>{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Era</th>
|
||||
<td>{{ magazine.era }}</td>
|
||||
<th scope="row">ISBN</th>
|
||||
<td>{{ magazine.ISBN | default:"-" }}</td>
|
||||
</tr>
|
||||
{% if magazine.description %}
|
||||
<tr>
|
||||
@@ -101,14 +107,6 @@
|
||||
<td>{{ magazine.description | safe }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th scope="row">Length</th>
|
||||
<td>{{ magazine.length }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Composition</th>
|
||||
<td>{% for t in magazine.get_type_count %}{{ t.count }}x {{ t.type }} {{t.category }}{% if not forloop.last %} » {% endif %}{% endfor %}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django import template
|
||||
from portal.models import Flatpage
|
||||
from bookshelf.models import Book, Catalog
|
||||
from bookshelf.models import Book, Catalog, Magazine
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@@ -8,10 +8,14 @@ register = template.Library()
|
||||
@register.inclusion_tag('bookshelf/bookshelf_menu.html')
|
||||
def show_bookshelf_menu():
|
||||
# FIXME: Filter out unpublished books and catalogs?
|
||||
books = Book.objects.exists()
|
||||
catalogs = Catalog.objects.exists()
|
||||
magazines = Magazine.objects.exists()
|
||||
return {
|
||||
"bookshelf_menu": (Book.objects.exists() or Catalog.objects.exists()),
|
||||
"books_menu": Book.objects.exists(),
|
||||
"catalogs_menu": Catalog.objects.exists(),
|
||||
"bookshelf_menu": (books or catalogs or magazines),
|
||||
"books_menu": books,
|
||||
"catalogs_menu": catalogs,
|
||||
"magazines_menu": magazines,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@ class Magazines(GetData):
|
||||
Magazine.objects.get_published(request.user)
|
||||
.all()
|
||||
.annotate(
|
||||
num_issues=Count(
|
||||
issues=Count(
|
||||
"issue",
|
||||
filter=Q(
|
||||
issue__in=(
|
||||
@@ -668,7 +668,7 @@ class GetMagazine(View):
|
||||
raise Http404
|
||||
data = [
|
||||
{
|
||||
"type": "issue",
|
||||
"type": "magazineissue",
|
||||
"item": i,
|
||||
}
|
||||
for i in magazine.issue.get_published(request.user).all()
|
||||
@@ -686,6 +686,7 @@ class GetMagazine(View):
|
||||
"title": magazine,
|
||||
"magazine": magazine,
|
||||
"data": data,
|
||||
"matches": paginator.count,
|
||||
"page_range": page_range,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from ram.utils import git_suffix
|
||||
|
||||
__version__ = "0.18.00"
|
||||
__version__ = "0.18.1"
|
||||
__version__ += git_suffix(__file__)
|
||||
|
||||
Reference in New Issue
Block a user