Added tag management

master
Laurent Morvillier 6 years ago
parent f60444c231
commit beae2cd3ef
  1. 2
      news/forms.py
  2. 35
      news/migrations/0006_auto_20191009_1004.py
  3. 22
      news/migrations/0007_auto_20191009_1009.py
  4. 10
      news/models.py
  5. 4
      news/static/news/css/app.css
  6. 18
      news/templates/base.html
  7. 7
      news/templates/news/index.html
  8. 14
      news/templates/news/static/about.html
  9. 4
      news/templates/news/static/contact.html
  10. 4
      news/templates/news/user/password_reset_html_email.html
  11. 1
      news/urls.py
  12. 16
      news/views.py

@ -19,6 +19,8 @@ class PostForm(forms.Form):
today_formatted = today.strftime("%Y-%m-%d %H:%M:%S") today_formatted = today.strftime("%Y-%m-%d %H:%M:%S")
image = forms.FileField(required=False) image = forms.FileField(required=False)
tags = forms.CharField(label='Tags (separated by a comma)', max_length=200, required=False)
pub_date = forms.DateTimeField(label='Optional publication date, example: ' + today_formatted, required=False) pub_date = forms.DateTimeField(label='Optional publication date, example: ' + today_formatted, required=False)
class SigninForm(forms.Form): class SigninForm(forms.Form):

@ -0,0 +1,35 @@
# Generated by Django 2.2.6 on 2019-10-09 10:04
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('news', '0005_auto_20190918_0918'),
]
operations = [
migrations.AlterField(
model_name='comment',
name='voters',
field=models.ManyToManyField(blank=True, related_name='voted_comments', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='player',
name='post',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='news.Post'),
),
migrations.AlterField(
model_name='post',
name='author',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='tag',
name='post',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='news.Post'),
),
]

@ -0,0 +1,22 @@
# Generated by Django 2.2.6 on 2019-10-09 10:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('news', '0006_auto_20191009_1004'),
]
operations = [
migrations.RemoveField(
model_name='tag',
name='post',
),
migrations.AddField(
model_name='tag',
name='post',
field=models.ManyToManyField(blank=True, null=True, to='news.Post'),
),
]

@ -12,7 +12,7 @@ class PostState(Enum):
USER_SUBMITTED = 3 USER_SUBMITTED = 3
class Post(models.Model): class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
title = models.CharField(max_length=200) title = models.CharField(max_length=200)
body = models.CharField(max_length=10000) body = models.CharField(max_length=10000)
url = models.CharField(max_length=200) url = models.CharField(max_length=200)
@ -39,6 +39,10 @@ class Post(models.Model):
flat.extend(children) flat.extend(children)
return flat return flat
def formatted_tags(self):
tag_names = map(lambda t: t.name, self.tag_set.all())
return ", ".join(tag_names)
class Comment(models.Model): class Comment(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True) author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE) post = models.ForeignKey(Post, on_delete=models.CASCADE)
@ -68,7 +72,7 @@ class Comment(models.Model):
class Player(models.Model): class Player(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
post = models.ForeignKey(Post, on_delete=models.CASCADE) post = models.ForeignKey(Post, on_delete=models.SET_NULL, null=True)
image_url = models.CharField(max_length=100) image_url = models.CharField(max_length=100)
def __str__(self): def __str__(self):
@ -77,6 +81,6 @@ class Player(models.Model):
class Tag(models.Model): class Tag(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
post = models.ForeignKey(Post, on_delete=models.CASCADE) post = models.ManyToManyField(Post, null=True, blank=True)
def __str__(self): def __str__(self):
return self.name return self.name

@ -181,13 +181,13 @@ a h1 {
position: relative; position: relative;
color: white; color: white;
/* border-bottom: 0px solid #111; */ /* border-bottom: 0px solid #111; */
border-top: 20px solid #111; /* border-top: 20px solid #111; */
} }
@media print, screen and (min-width: 40em) { @media print, screen and (min-width: 40em) {
.imgcontainer { .imgcontainer {
width: 600px; width: 600px;
/* border-bottom: 10px solid #111; */ /* border-bottom: 10px solid #111; */
border-top: 20px solid #111; /* border-top: 20px solid #111; */
} }
} }

@ -8,6 +8,22 @@
<link rel="stylesheet" type="text/css" href="{% static 'news/css/foundation.min.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'news/css/foundation.min.css' %}">
<link rel="shortcut icon" type="image/png" href="{% static 'image/favicon.png' %}"/> <link rel="shortcut icon" type="image/png" href="{% static 'image/favicon.png' %}"/>
<title>{% block title %}My amazing site{% endblock %}</title> <title>{% block title %}My amazing site{% endblock %}</title>
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//www.pokerrumble.net/matomo/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head> </head>
<body> <body>
@ -61,6 +77,8 @@
<footer> <footer>
<a href="{% url 'news:contact' %}">Contact</a> <a href="{% url 'news:contact' %}">Contact</a>
<br/>
<a href="{% url 'news:about' %}">About</a>
<p>Copyright © 2019 Poker Rumble</p> <p>Copyright © 2019 Poker Rumble</p>
</footer> </footer>

@ -2,7 +2,7 @@
{% load static %} {% load static %}
{% block title %}My amazing blog{% endblock %} {% block title %}Poker Rumble - {% endblock %}
{% block content %} {% block content %}
{% if latest_post_list %} {% if latest_post_list %}
@ -95,6 +95,11 @@
<iframe class="youtube" src="https://www.youtube.com/embed/{{ post.url }}"></iframe> <iframe class="youtube" src="https://www.youtube.com/embed/{{ post.url }}"></iframe>
{% endif %} {% endif %}
<!-- {% if post.tag_set.count > 0 %}
<p>tags: {{ post.formatted_tags }}</p>
{% endif %} -->
</article> </article>
<!-- </div> --> <!-- </div> -->

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block title %}About - Poker Rumble{% endblock %}
{% block content %}
<h1>About</h1>
<p>
This site is owned by Stax River.
It is hosted by ALWAYSDATA, 91 rue du Faubourg Saint-Honoré, 75008 Paris (phone: +33 1 84 16 23 40).
</p>
{% endblock content %}

@ -1,13 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Contact{% endblock %} {% block title %}Contact - Poker Rumble{% endblock %}
{% block content %} {% block content %}
<h1>Contact</h1> <h1>Contact</h1>
<p> <p>
Please contact us directly on social media! Please contact us directly on social media, @pokerrumble on <a href="https://twitter.com/pokerrumble">twitter</a> and <a href="https://www.instagram.com/pokerrumble">instagram</a>!
</p> </p>
{% endblock content %} {% endblock content %}

@ -1,3 +1,3 @@
Someone asked for password reset for email {{ email }}. Someone asked for a password reset for email {{ email }}.
Follow the link below: Please follow the link below:
{{ protocol}}://{{ domain }}{% url 'news:password_reset_confirm' uidb64=uid token=token %} {{ protocol}}://{{ domain }}{% url 'news:password_reset_confirm' uidb64=uid token=token %}

@ -8,6 +8,7 @@ app_name = 'news'
urlpatterns = [ urlpatterns = [
# Static # Static
path('contact', TemplateView.as_view(template_name='news/static/contact.html'), name='contact'), path('contact', TemplateView.as_view(template_name='news/static/contact.html'), name='contact'),
path('about', TemplateView.as_view(template_name='news/static/about.html'), name='about'),
# Posts # Posts
path('', views.index, name='index'), path('', views.index, name='index'),
path('<int:post_id>', views.post, name='post'), path('<int:post_id>', views.post, name='post'),

@ -11,7 +11,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
from django.db.models import Q from django.db.models import Q
from django.utils.html import strip_tags from django.utils.html import strip_tags
from .models import Post, Comment, PostState from .models import Post, Comment, PostState, Tag
from .forms import PostForm, CustomUserCreationForm, SigninForm from .forms import PostForm, CustomUserCreationForm, SigninForm
from datetime import datetime from datetime import datetime
import logging import logging
@ -106,6 +106,9 @@ def submission(request):
post.url = form.cleaned_data['url'] post.url = form.cleaned_data['url']
post.style = form.cleaned_data['style'] post.style = form.cleaned_data['style']
tags = parsed_tags(form.cleaned_data['tags'])
post.tag_set.add(*tags)
file = request.FILES.get('image', None) file = request.FILES.get('image', None)
if file is not None: if file is not None:
filename = str(uuid.uuid4()) filename = str(uuid.uuid4())
@ -128,6 +131,15 @@ def submission(request):
return render(request, 'news/submission.html', {'form': form}) return render(request, 'news/submission.html', {'form': form})
def parsed_tags(tag_strings):
tags = []
separated_tags_strings = tag_strings.split(",")
for tag_string in separated_tags_strings:
tag, created = Tag.objects.get_or_create(name=tag_string.strip())
tag.save()
tags.append(tag)
return tags
def handle_uploaded_file(filename, f): def handle_uploaded_file(filename, f):
with open(settings.MEDIA_ROOT + filename, 'wb+') as destination: with open(settings.MEDIA_ROOT + filename, 'wb+') as destination:
for chunk in f.chunks(): for chunk in f.chunks():
@ -144,7 +156,7 @@ def comment_with_parent(request, post_id, comment_id):
comment.post = get_object_or_404(Post, pk=post_id) comment.post = get_object_or_404(Post, pk=post_id)
if comment_id is not None: if comment_id is not None:
comment.parent_comment = get_object_or_404(Comment, pk=comment_id) comment.parent_comment = get_object_or_404(Comment, pk=comment_id)
comment.body = strip_tags(request.POST['body']) comment.body = strip_tags(request.POST['body']) # removes HTML tags
comment.save() comment.save()
comment.voters.add(request.user) comment.voters.add(request.user)
comment.save() comment.save()

Loading…
Cancel
Save