Save HTML for each thought to the DB for performance
This commit is contained in:
parent
650a845611
commit
8fe3852040
|
@ -5,6 +5,8 @@ python-decouple~=3.6
|
|||
jetforce~=0.9.0
|
||||
|
||||
django-extensions~=3.2.1
|
||||
django-debug-toolbar~=3.6.0
|
||||
progressbar~=4.0.0
|
||||
|
||||
git+https://github.com/django-haystack/django-haystack.git
|
||||
git+https://tildegit.org/matthias/xapian-haystack.git
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
from progressbar import progressbar
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from thoughts.models import Thought
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
for t in progressbar(Thought.objects.all()):
|
||||
# Saving forces us to re-generate HTML content
|
||||
t.save()
|
|
@ -0,0 +1,24 @@
|
|||
# Generated by Django 4.0.3 on 2022-09-17 17:54
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('thoughts', '0006_alter_thought_text'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='thought',
|
||||
name='html_content',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='thought',
|
||||
name='posted',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
]
|
|
@ -8,16 +8,21 @@ from django.db import models
|
|||
from django.utils import timezone
|
||||
from django.utils.text import normalize_newlines
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
class Thought(models.Model):
|
||||
text = models.CharField(max_length=140, blank=True)
|
||||
extended_text = models.TextField(blank=True)
|
||||
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
|
||||
posted = models.DateTimeField(auto_now_add=True)
|
||||
posted = models.DateTimeField(default=timezone.now)
|
||||
timezone_offset = models.IntegerField() # The number of minutes behind UTC we were when this was posted
|
||||
media = models.FileField(upload_to="", blank=True) # A single image, video, or sound clip per post
|
||||
media_alt = models.TextField(blank=True) # An optional transcription of the Thought's media
|
||||
html_content = models.TextField(blank=True) # The rendered text for this thought
|
||||
|
||||
def save(self):
|
||||
self.update_html_content(commit=False)
|
||||
super().save()
|
||||
|
||||
def get_media_type(self):
|
||||
if not self.media:
|
||||
|
@ -40,6 +45,17 @@ class Thought(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return f"/?show={str(self.uuid)}"
|
||||
|
||||
def get_html_content(self, authenticated=False):
|
||||
return render_to_string("thoughts/thought.html", {"thought": self, "authenticated": authenticated})
|
||||
|
||||
def get_html_content_authenticated(self):
|
||||
return self.get_html_content(authenticated=True)
|
||||
|
||||
def update_html_content(self, commit=True):
|
||||
self.html_content = self.get_html_content()
|
||||
if commit:
|
||||
self.save()
|
||||
|
||||
@classmethod
|
||||
def find(cls, identifier):
|
||||
try:
|
||||
|
|
|
@ -56,59 +56,17 @@
|
|||
</nav>
|
||||
{% endif %}
|
||||
|
||||
{% load tz %}
|
||||
|
||||
{% for thought in thoughts %}
|
||||
<div class="thought{% if thought.uuid == highlighted %} highlighted{% endif %}" id="{{ thought.uuid }}">
|
||||
<div class="main">
|
||||
<span class="main-text text">{{ thought.text|urlize }}</span>
|
||||
</div>
|
||||
|
||||
{% with file_type=thought.get_media_type %}
|
||||
{% if file_type or thought.extended_text.strip %}
|
||||
<div class="extended">
|
||||
{% if thought.extended_text.strip %}
|
||||
<span class="extended-text text">{{ thought.extended_text|urlize }}</span>
|
||||
{% if thought.uuid == highlighted %}
|
||||
{% if authenticated %}
|
||||
{{ thought.get_html_content_authenticated }}
|
||||
{% else %}
|
||||
{{ thought.get_html_content}}
|
||||
{% endif %}
|
||||
{% if file_type == "png" or file_type == "jpeg" or file_type == "jpg" %}
|
||||
<img src="{{ thought.media.url }}" class="extended-media" alt="{{ thought.media_alt }}">
|
||||
{% elif file_type == "m4a" or file_type == "mp3" or file_type == "aac" %}
|
||||
<audio controls src="{{ thought.media.url }}" class="extended-media"></audio>
|
||||
{% if thought.media_alt %}
|
||||
<button class="transcript-button">View transcription</button>
|
||||
<div class="transcript-label">Transcript</div>
|
||||
<div class="transcript">{{ thought.media_alt|urlize }}</div>
|
||||
{% else %}
|
||||
{{ thought.html_content|safe }}
|
||||
{% endif %}
|
||||
{% elif file_type == "mov" or file_type == "mp4" %}
|
||||
<video src="{{ thought.media.url }}" controls class="extended-media"></video>
|
||||
{% if thought.media_alt %}
|
||||
<button class="transcript-button">View description</button>
|
||||
<div class="transcript-label">Description</div>
|
||||
<div class="transcript">{{ thought.media_alt|urlize }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class="thought-end">
|
||||
<span class="permalink">
|
||||
<a class="button" href="/?show={{thought.uuid}}">Link</a>
|
||||
</span>
|
||||
{% if thought.uuid == highlighted and authenticated %}
|
||||
<span class="permalink edit-link">
|
||||
<a class="button" href="/post?editing={{thought.uuid}}">Edit</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span class="timestamp">
|
||||
{% timezone thought.get_timezone %}
|
||||
{{ thought.posted|time:"g:i a" }}
|
||||
{{ thought.posted|date:"M d, Y" }},
|
||||
|
||||
UTC{{ thought.get_offset_hours }}
|
||||
{% endtimezone %}
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<div class="main">
|
||||
<span class="main-text text">{{ thought.text|urlize }}</span>
|
||||
</div>
|
||||
|
||||
{% with file_type=thought.get_media_type %}
|
||||
{% if file_type or thought.extended_text.strip %}
|
||||
<div class="extended">
|
||||
{% if thought.extended_text.strip %}
|
||||
<span class="extended-text text">{{ thought.extended_text|urlize }}</span>
|
||||
{% endif %}
|
||||
{% if file_type == "png" or file_type == "jpeg" or file_type == "jpg" %}
|
||||
<img src="{{ thought.media.url }}" class="extended-media" alt="{{ thought.media_alt }}">
|
||||
{% elif file_type == "m4a" or file_type == "mp3" or file_type == "aac" %}
|
||||
<audio controls src="{{ thought.media.url }}" class="extended-media"></audio>
|
||||
{% if thought.media_alt %}
|
||||
<button class="transcript-button">View transcription</button>
|
||||
<div class="transcript-label">Transcript</div>
|
||||
<div class="transcript">{{ thought.media_alt|urlize }}</div>
|
||||
{% endif %}
|
||||
{% elif file_type == "mov" or file_type == "mp4" %}
|
||||
<video src="{{ thought.media.url }}" controls class="extended-media"></video>
|
||||
{% if thought.media_alt %}
|
||||
<button class="transcript-button">View description</button>
|
||||
<div class="transcript-label">Description</div>
|
||||
<div class="transcript">{{ thought.media_alt|urlize }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class="thought-end">
|
||||
<span class="permalink">
|
||||
<a class="button" href="/?show={{thought.uuid}}">Link</a>
|
||||
</span>
|
||||
|
||||
|
||||
{% if authenticated %}
|
||||
<span class="permalink edit-link">
|
||||
<a class="button" href="/post?editing={{thought.uuid}}">Edit</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% load tz %}
|
||||
<span class="timestamp">
|
||||
{% timezone thought.get_timezone %}
|
||||
{{ thought.posted|time:"g:i a" }}
|
||||
{{ thought.posted|date:"M d, Y" }},
|
||||
|
||||
UTC{{ thought.get_offset_hours }}
|
||||
{% endtimezone %}
|
||||
</span>
|
||||
</div>
|
||||
<hr>
|
|
@ -31,6 +31,7 @@ PASSWORD = config("PASSWORD", default="password")
|
|||
ALLOWED_HOSTS = ["thoughts.learnerpages.com"]
|
||||
if DEBUG:
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
INTERNAL_IPS = ["localhost", "127.0.0.1"]
|
||||
|
||||
def split_string(string):
|
||||
return string.split(",")
|
||||
|
@ -44,6 +45,7 @@ INSTALLED_APPS = [
|
|||
"django.contrib.staticfiles",
|
||||
|
||||
"django_extensions",
|
||||
"debug_toolbar",
|
||||
|
||||
"haystack",
|
||||
|
||||
|
@ -66,6 +68,7 @@ HAYSTACK_CONNECTIONS = {
|
|||
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 1000000
|
||||
|
||||
MIDDLEWARE = [
|
||||
"debug_toolbar.middleware.DebugToolbarMiddleware",
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
|
|
|
@ -9,5 +9,6 @@ urlpatterns = [
|
|||
path("about", views.about, name="about"),
|
||||
path("login", views.login, name="login"),
|
||||
path("post", views.post, name="post"),
|
||||
path("search", views.search, name="thoughts_search")
|
||||
path("search", views.search, name="thoughts_search"),
|
||||
path('__debug__/', include('debug_toolbar.urls')),
|
||||
] + (static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG else [])
|
||||
|
|
Loading…
Reference in New Issue