from django.contrib import admin
# Register your models here.
-from .models import Tag, Author, Work, Quote
-admin.site.register(Tag)
-admin.site.register(Author)
-admin.site.register(Work)
-admin.site.register(Quote)
+from .models import AuthorTag, WorkTag, QuoteTag, Author, Work, Quote
+
+@admin.register(Author)
+class AuthorAdmin(admin.ModelAdmin):
+ fields = ('name', 'birth_date', 'death_date', 'tags',
+ 'notes', 'pvt_notes', 'creation_date', 'last_modification')
+ readonly_fields = ('creation_date', 'last_modification')
+
+@admin.register(Work)
+class WorkAdmin(admin.ModelAdmin):
+ fields = ('name', 'author', 'date', 'tags',
+ 'notes', 'pvt_notes', 'creation_date', 'last_modification')
+ readonly_fields = ('creation_date', 'last_modification')
+
+@admin.register(Quote)
+class QuoteAdmin(admin.ModelAdmin):
+ fields = ('text', 'work', 'tags',
+ 'notes', 'pvt_notes', 'creation_date', 'last_modification')
+ readonly_fields = ('creation_date', 'last_modification')
+
+admin.site.register(AuthorTag)
+admin.site.register(WorkTag)
+admin.site.register(QuoteTag)
# -*- coding: utf-8 -*-
+# Generated by Django 1.10.2 on 2016-10-31 23:03
from __future__ import unicode_literals
from django.db import migrations, models
+import django.db.models.deletion
+import quotes.localmodels
class Migration(migrations.Migration):
+ initial = True
+
dependencies = [
]
migrations.CreateModel(
name='Author',
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(help_text=b'Name of the author', max_length=100)),
- ('notes', models.TextField(help_text=b'Notes about the author; may be left blank. Will not be HTML-escaped.', blank=True)),
- ('pvt_notes', models.TextField(help_text=b'Notes about the author; not displayed on the public interface', blank=True)),
- ('birth_date', models.DateField(help_text=b'Date of birth', null=True, blank=True)),
- ('death_date', models.DateField(help_text=b'Date of death (leave blank if still alive!)', null=True, blank=True)),
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(help_text=b'Name of the author', max_length=100, unique=True)),
+ ('notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the author; may be left blank. Will not be HTML-escaped.')),
+ ('pvt_notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the author; not displayed on the public interface')),
+ ('birth_date', models.DateField(blank=True, help_text=b'Date of birth', null=True)),
+ ('death_date', models.DateField(blank=True, help_text=b'Date of death (leave blank if still alive!)', null=True)),
],
),
migrations.CreateModel(
- name='Context',
+ name='AuthorTag',
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(help_text=b'Name of the context for the quote (title of the work or speech it appears in)', max_length=100)),
- ('date', models.DateField(help_text=b'Date of the quote', null=True, blank=True)),
- ('notes', models.TextField(help_text=b'Notes about the work; may be left blank. Will not be HTML-escaped. XXX: offer a WYSIWYG editor', blank=True)),
- ('pvt_notes', models.TextField(help_text=b'Notes about the work; not displayed on the public interface', blank=True)),
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tag', models.CharField(max_length=100, unique=True)),
],
+ options={
+ 'abstract': False,
+ },
),
migrations.CreateModel(
name='Quote',
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('text', models.TextField()),
- ('notes', models.TextField(help_text=b'Notes about the quote; may be left blank. Will not be HTML-escaped. XXX: offer a WYSIWYG editor', blank=True)),
- ('pvt_notes', models.TextField(help_text=b'Notes about the quote; not displayed on the public interface', blank=True)),
- ('context', models.ForeignKey(to='quotes.Context')),
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('text', quotes.localmodels.HTMLField()),
+ ('notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the quote; may be left blank. Will not be HTML-escaped. XXX: offer a WYSIWYG editor')),
+ ('pvt_notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the quote; not displayed on the public interface')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='QuoteTag',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tag', models.CharField(max_length=100, unique=True)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Work',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(help_text=b'Name of the context for the quote (title of the work or speech it appears in)', max_length=100, unique=True)),
+ ('date', models.DateField(blank=True, help_text=b'Date of the quote', null=True)),
+ ('notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the work; may be left blank. Will not be HTML-escaped. XXX: offer a WYSIWYG editor')),
+ ('pvt_notes', quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the work; not displayed on the public interface')),
+ ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quotes.Author')),
],
),
migrations.CreateModel(
- name='Tag',
+ name='WorkTag',
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('tag', models.CharField(max_length=100)),
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tag', models.CharField(max_length=100, unique=True)),
],
+ options={
+ 'abstract': False,
+ },
),
migrations.AddField(
- model_name='quote',
+ model_name='work',
name='tags',
- field=models.ManyToManyField(to='quotes.Tag', blank=True),
+ field=models.ManyToManyField(blank=True, to='quotes.WorkTag'),
),
migrations.AddField(
- model_name='context',
+ model_name='quote',
name='tags',
- field=models.ManyToManyField(to='quotes.Tag', blank=True),
+ field=models.ManyToManyField(blank=True, to='quotes.QuoteTag'),
+ ),
+ migrations.AddField(
+ model_name='quote',
+ name='work',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quotes.Work'),
),
migrations.AddField(
model_name='author',
name='tags',
- field=models.ManyToManyField(to='quotes.Tag', blank=True),
+ field=models.ManyToManyField(blank=True, to='quotes.AuthorTag'),
),
]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.2 on 2016-10-31 23:18
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.utils.timezone
+import quotes.localmodels
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('quotes', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='author',
+ name='creation_date',
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='author',
+ name='last_modification',
+ field=models.DateTimeField(auto_now=True),
+ ),
+ migrations.AddField(
+ model_name='quote',
+ name='creation_date',
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='quote',
+ name='last_modification',
+ field=models.DateTimeField(auto_now=True),
+ ),
+ migrations.AddField(
+ model_name='work',
+ name='creation_date',
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='work',
+ name='last_modification',
+ field=models.DateTimeField(auto_now=True),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; may be left blank. Displayed on the public pages'),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='pvt_notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; not displayed on the public interface'),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='tags',
+ field=models.ManyToManyField(blank=True, help_text=b'Not implemented yet', to='quotes.AuthorTag'),
+ ),
+ migrations.AlterField(
+ model_name='quote',
+ name='notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; may be left blank. Displayed on the public pages'),
+ ),
+ migrations.AlterField(
+ model_name='quote',
+ name='pvt_notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; not displayed on the public interface'),
+ ),
+ migrations.AlterField(
+ model_name='work',
+ name='notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; may be left blank. Displayed on the public pages'),
+ ),
+ migrations.AlterField(
+ model_name='work',
+ name='pvt_notes',
+ field=quotes.localmodels.HTMLField(blank=True, help_text=b'Notes about the entry; not displayed on the public interface'),
+ ),
+ migrations.AlterField(
+ model_name='work',
+ name='tags',
+ field=models.ManyToManyField(blank=True, help_text=b'Not implemented yet', to='quotes.WorkTag'),
+ ),
+ ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('quotes', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='context',
- name='author',
- field=models.ForeignKey(default=1, to='quotes.Author'),
- preserve_default=False,
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('quotes', '0002_context_author'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Work',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(help_text=b'Name of the context for the quote (title of the work or speech it appears in)', max_length=100)),
- ('date', models.DateField(help_text=b'Date of the quote', null=True, blank=True)),
- ('notes', models.TextField(help_text=b'Notes about the work; may be left blank. Will not be HTML-escaped. XXX: offer a WYSIWYG editor', blank=True)),
- ('pvt_notes', models.TextField(help_text=b'Notes about the work; not displayed on the public interface', blank=True)),
- ('author', models.ForeignKey(to='quotes.Author')),
- ('tags', models.ManyToManyField(to='quotes.Tag', blank=True)),
- ],
- ),
- migrations.RemoveField(
- model_name='context',
- name='author',
- ),
- migrations.RemoveField(
- model_name='context',
- name='tags',
- ),
- migrations.AlterField(
- model_name='quote',
- name='context',
- field=models.ForeignKey(to='quotes.Work'),
- ),
- migrations.DeleteModel(
- name='Context',
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('quotes', '0003_auto_20161009_2254'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='quote',
- old_name='context',
- new_name='work',
- ),
- ]
from localmodels import HTMLField
# Create your models here.
-class Tag(models.Model):
- tag = models.CharField(max_length=100)
+class BaseTag(models.Model):
+ tag = models.CharField(max_length=100, unique=True)
+
def __unicode__(self):
return self.tag
-class Author(models.Model):
- name = models.CharField(max_length=100,
- help_text="Name of the author")
+ class Meta(object):
+ abstract = True
+
+class AuthorTag(BaseTag): pass
+class WorkTag(BaseTag): pass
+class QuoteTag(BaseTag): pass
+
+class CommonData(models.Model):
+ creation_date = models.DateTimeField(auto_now_add=True)
+ last_modification = models.DateTimeField(auto_now=True)
+
notes = HTMLField(blank=True, help_text= \
- "Notes about the author; may be left blank. Will \
- not be HTML-escaped.",)
+ "Notes about the entry; may be left blank. Displayed \
+ on the public pages")
pvt_notes = HTMLField(blank=True, help_text= \
- "Notes about the author; not displayed on \
- the public interface",)
- tags = models.ManyToManyField(Tag, blank=True)
+ "Notes about the entry; not displayed on \
+ the public interface")
+
+ class Meta(object):
+ abstract = True
+
+class Author(CommonData):
+ name = models.CharField(max_length=100,
+ help_text="Name of the author",
+ unique=True)
+
+ tags = models.ManyToManyField(AuthorTag, blank=True,
+ help_text='Not implemented yet')
birth_date = models.DateField(blank=True, null=True,
help_text="Date of birth")
# models.CharField(max_length=1, choices=self.PRECISION_CHOICES,
# default=self.DAY, **kwargs)
-class Work(models.Model):
+class Work(CommonData):
name = models.CharField(max_length=100,
help_text="Name of the context for the quote \
- (title of the work or speech it appears in)")
+ (title of the work or speech it appears in)",
+ unique=True)
author = models.ForeignKey(Author)
date = models.DateField(blank=True, null=True,
help_text="Date of the quote")
- tags = models.ManyToManyField(Tag, blank=True)
-
- notes = HTMLField(blank=True, help_text= \
- "Notes about the work; may be left blank. Will \
- not be HTML-escaped. XXX: offer a WYSIWYG editor")
- pvt_notes = HTMLField(blank=True, help_text= \
- "Notes about the work; not displayed on \
- the public interface")
+ tags = models.ManyToManyField(WorkTag, blank=True,
+ help_text='Not implemented yet')
def __str__(self):
return "%s: %s (%s)" % (self.author.name, self.name, self.date)
-class Quote(models.Model):
+class Quote(CommonData):
text = HTMLField()
- tags = models.ManyToManyField(Tag, blank=True)
+ tags = models.ManyToManyField(QuoteTag, blank=True)
work = models.ForeignKey(Work)
- notes = HTMLField(blank=True, help_text= \
- "Notes about the quote; may be left blank. Will \
- not be HTML-escaped. XXX: offer a WYSIWYG editor")
- pvt_notes = HTMLField(blank=True, help_text= \
- "Notes about the quote; not displayed on \
- the public interface")
-
def __str__(self):
return self.work.author.name + ": " + self.text
from django.test import TestCase, Client
# Create your tests here.
-from .models import Tag, Author, Work, Quote
+from .models import QuoteTag, Author, Work, Quote
import re
import lxml.etree
q1 = Quote.objects.create(text="<p>Quote01, two tags</p>",
work=w1,
notes="<p>Some notes for the quote</p>")
- t1 = Tag.objects.create(tag="tag01-1")
- t2 = Tag.objects.create(tag="tag01-2")
+ t1 = QuoteTag.objects.create(tag="tag01-1")
+ t2 = QuoteTag.objects.create(tag="tag01-2")
q1.tags.add(t1, t2)
a2 = Author.objects.create(name="Author without notes")
from random import randint
-from .models import Author, Work, Quote, Tag
+from .models import Author, Work, Quote, QuoteTag
# Create your views here.
def onequote(request, quote_id):
return onequote(request, randint(1, count))
def tags(request, tag_id):
- tag = Tag.objects.get(id=tag_id)
+ tag = QuoteTag.objects.get(id=tag_id)
context = { 'tag' : tag }
return render(request, 'quotes/tag.html', context)