port over guestbook
parent
9a071bd435
commit
9c3d2469d2
|
@ -0,0 +1,6 @@
|
|||
from django.contrib import admin
|
||||
from .models import GuestbookMessage
|
||||
|
||||
@admin.register(GuestbookMessage)
|
||||
class TicketAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'datetime_created', 'msg')
|
|
@ -0,0 +1,47 @@
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms import Form, CharField, EmailField, Textarea, ChoiceField
|
||||
|
||||
from common.forms import CaptchaField
|
||||
|
||||
|
||||
# this should go in something like redis. I refuse, however, to involve redis
|
||||
# in all of this until i have 2-3 more usecases.
|
||||
# TODO generalize
|
||||
submission_throttle = {}
|
||||
|
||||
def throttle_submission(name):
|
||||
last_submission = submission_throttle.get(name)
|
||||
now = datetime.now()
|
||||
if last_submission is None\
|
||||
or now - last_submission > timedelta(minutes=30):
|
||||
submission_throttle[name] = datetime.now()
|
||||
else:
|
||||
raise ValidationError('you have submitted pretty recently. try again in a bit.')
|
||||
|
||||
def validate_msg_text(msg):
|
||||
if len(msg) == 0:
|
||||
raise ValidationError('message cannot be empty')
|
||||
if len(msg) > 500:
|
||||
raise ValidationError('too long')
|
||||
|
||||
|
||||
class GuestbookForm(Form):
|
||||
name = CharField(label='name!')
|
||||
msg = CharField(
|
||||
widget=Textarea,
|
||||
label="message!",
|
||||
validators=(validate_msg_text,),
|
||||
)
|
||||
captcha = CaptchaField()
|
||||
|
||||
def clean(self):
|
||||
result = super().clean()
|
||||
|
||||
throttle_submission(result['name'])
|
||||
|
||||
if self.errors:
|
||||
raise ValidationError('oops, looks like there were some problems below.')
|
||||
|
||||
return result
|
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-12-20 05:08
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='GuestbookMessage',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=50)),
|
||||
('msg', models.TextField(max_length=500)),
|
||||
('datetime_created', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
from django.db.models import Model, TextField, CharField, DateTimeField
|
||||
|
||||
|
||||
class GuestbookMessage(Model):
|
||||
name = CharField(blank=False, null=False, max_length=50)
|
||||
msg = TextField(blank=False, null=False, max_length=500)
|
||||
datetime_created = DateTimeField(auto_now_add=True)
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<title>tilde.town guestbook</title>
|
||||
<meta charset="UTF-8">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #E0B0FF;
|
||||
}
|
||||
#message th {
|
||||
text-align:left;
|
||||
}
|
||||
#message {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#message th,td {
|
||||
border: 1px solid #ff1ac6;
|
||||
}
|
||||
#message input[type=submit] {
|
||||
font-size:150%;
|
||||
}
|
||||
#message ul.errorlist {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
padding-left:0;
|
||||
}
|
||||
#message ul.errorlist li:before {
|
||||
content: "~! ";
|
||||
}
|
||||
#message ul.errorlist li {
|
||||
background-color:black;
|
||||
color:white;
|
||||
border: .5em dashed red;
|
||||
font-family:arial;
|
||||
padding:2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>tilde.town guestbook</h1>
|
||||
<marquee>~*~*~*~*say hello*~*~*~*~</marquee>
|
||||
<form id="message" action="{% url 'guestbook:guestbook' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{form.as_table}}
|
||||
</table>
|
||||
<input type="submit" value="sign" >
|
||||
</form>
|
||||
|
||||
{% for m in messages %}
|
||||
<p>
|
||||
{{m.name}} says: {{m.msg}}
|
||||
</p>
|
||||
{% endfor %}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from .views import GuestbookView
|
||||
|
||||
app_name = 'guestbook'
|
||||
urlpatterns = [
|
||||
url(r'^$', GuestbookView.as_view(), name='guestbook'),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
from django.shortcuts import redirect
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic.edit import FormView
|
||||
|
||||
from .forms import GuestbookForm
|
||||
from .models import GuestbookMessage
|
||||
|
||||
|
||||
class GuestbookView(FormView):
|
||||
form_class = GuestbookForm
|
||||
template_name = 'guestbook/guestbook.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['messages'] = GuestbookMessage.objects.order_by('-datetime_created')
|
||||
return ctx
|
||||
|
||||
def form_valid(self, form):
|
||||
del form.cleaned_data['captcha']
|
||||
t = GuestbookMessage.objects.create(**form.cleaned_data)
|
||||
return redirect('guestbook:guestbook')
|
|
@ -26,6 +26,7 @@ INSTALLED_APPS = [
|
|||
'django.contrib.staticfiles',
|
||||
'users',
|
||||
'help',
|
||||
'guestbook'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
|
|
@ -4,5 +4,6 @@ from django.contrib import admin
|
|||
urlpatterns = [
|
||||
url(r'^help/', include('help.urls')),
|
||||
url(r'^users/', include('users.urls')),
|
||||
url(r'^guestbook/', include('guestbook.urls')),
|
||||
url(r'^admin/', admin.site.urls),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue