diff options
Diffstat (limited to 'api')
-rw-r--r-- | api/admin.py | 15 | ||||
-rw-r--r-- | api/migrations/0006_add_help_texts.py | 44 | ||||
-rw-r--r-- | api/models.py | 102 | ||||
-rw-r--r-- | api/tests/test_models.py | 43 |
4 files changed, 165 insertions, 39 deletions
diff --git a/api/admin.py b/api/admin.py index 4185d360..54cb33ea 100644 --- a/api/admin.py +++ b/api/admin.py @@ -1,3 +1,14 @@ -# from django.contrib import admin +from django.contrib import admin -# Register your models here. +from .models import ( + DocumentationLink, Member, + OffTopicChannelName, Role, + SnakeName +) + + +admin.site.register(DocumentationLink) +admin.site.register(Member) +admin.site.register(OffTopicChannelName) +admin.site.register(Role) +admin.site.register(SnakeName) diff --git a/api/migrations/0006_add_help_texts.py b/api/migrations/0006_add_help_texts.py new file mode 100644 index 00000000..a57d2289 --- /dev/null +++ b/api/migrations/0006_add_help_texts.py @@ -0,0 +1,44 @@ +# Generated by Django 2.1.1 on 2018-09-21 20:26 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0005_user'), + ] + + operations = [ + migrations.AlterField( + model_name='documentationlink', + name='base_url', + field=models.URLField(help_text='The base URL from which documentation will be available for this project. Used to generate links to various symbols within this package.'), + ), + migrations.AlterField( + model_name='documentationlink', + name='inventory_url', + field=models.URLField(help_text='The URL at which the Sphinx inventory is available for this package.'), + ), + migrations.AlterField( + model_name='documentationlink', + name='package', + field=models.CharField(help_text='The Python package name that this documentation link belongs to.', max_length=50, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='offtopicchannelname', + name='name', + field=models.CharField(help_text='The actual channel name that will be used on our Discord server.', max_length=96, primary_key=True, serialize=False, validators=[django.core.validators.RegexValidator(regex='^[a-z0-9-]+$')]), + ), + migrations.AlterField( + model_name='snakename', + name='name', + field=models.CharField(help_text="The regular name for this snake, e.g. 'Python'.", max_length=100, primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='snakename', + name='scientific', + field=models.CharField(help_text="The scientific name for this snake, e.g. 'Python bivittatus'.", max_length=150), + ), + ] diff --git a/api/models.py b/api/models.py index 4e4de9e0..6b681ebc 100644 --- a/api/models.py +++ b/api/models.py @@ -1,31 +1,80 @@ +from operator import itemgetter + from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator from django.db import models -class DocumentationLink(models.Model): +class ModelReprMixin: + """ + Adds a `__repr__` method to the model subclassing this + mixin which will display the model's class name along + with all parameters used to construct the object. + """ + + def __repr__(self): + attributes = ' '.join( + f'{attribute}={value!r}' + for attribute, value in sorted( + self.__dict__.items(), + key=itemgetter(0) + ) + if not attribute.startswith('_') + ) + return f'<{self.__class__.__name__}({attributes})>' + + +class DocumentationLink(ModelReprMixin, models.Model): """A documentation link used by the `!docs` command of the bot.""" - package = models.CharField(primary_key=True, max_length=50) - base_url = models.URLField() - inventory_url = models.URLField() + package = models.CharField( + primary_key=True, + max_length=50, + help_text="The Python package name that this documentation link belongs to." + ) + base_url = models.URLField( + help_text=( + "The base URL from which documentation will be available for this project. " + "Used to generate links to various symbols within this package." + ) + ) + inventory_url = models.URLField( + help_text="The URL at which the Sphinx inventory is available for this package." + ) + def __str__(self): + return f"{self.package} - {self.base_url}" -class OffTopicChannelName(models.Model): + +class OffTopicChannelName(ModelReprMixin, models.Model): name = models.CharField( primary_key=True, max_length=96, - validators=(RegexValidator(regex=r'^[a-z0-9-]+$'),) + validators=(RegexValidator(regex=r'^[a-z0-9-]+$'),), + help_text="The actual channel name that will be used on our Discord server." ) + def __str__(self): + return self.name + -class SnakeName(models.Model): +class SnakeName(ModelReprMixin, models.Model): """A snake name used by the bot's snake cog.""" - name = models.CharField(primary_key=True, max_length=100) - scientific = models.CharField(max_length=150) + name = models.CharField( + primary_key=True, + max_length=100, + help_text="The regular name for this snake, e.g. 'Python'." + ) + scientific = models.CharField( + max_length=150, + help_text="The scientific name for this snake, e.g. 'Python bivittatus'." + ) + + def __str__(self): + return f"{self.name} ({self.scientific})" -class Role(models.Model): +class Role(ModelReprMixin, models.Model): """A role on our Discord server.""" id = models.BigIntegerField( # noqa @@ -65,8 +114,11 @@ class Role(models.Model): help_text="The integer value of the permission bitset of this role from Discord." ) + def __str__(self): + return self.name + -class Member(models.Model): +class Member(ModelReprMixin, models.Model): """A member of our Discord server.""" id = models.BigIntegerField( # noqa @@ -105,29 +157,5 @@ class Member(models.Model): help_text="Any roles this user has on our server." ) - -class Tag(models.Model): - """A tag providing (hopefully) useful content, shown by the bot.""" - - author = models.ForeignKey( - Member, - help_text="The user that originally created this tag.", - on_delete=models.CASCADE - ) - title = models.CharField( - max_length=256, - help_text="The title of this tag, displayed in the Embed.", - unique=True - ) - content = models.CharField( - max_length=2048, - help_text="The content of this tag, displayed in the Embed." - ) - image_url = models.URLField( - null=True, - help_text="An optional image to display in the tag embed." - ) - thumbnail_url = models.URLField( - null=True, - help_text="An optional thumbnail to display in the tag embed." - ) + def __str__(self): + return f"{self.name}#{self.discriminator}" diff --git a/api/tests/test_models.py b/api/tests/test_models.py new file mode 100644 index 00000000..ff4bb226 --- /dev/null +++ b/api/tests/test_models.py @@ -0,0 +1,43 @@ +from django.test import SimpleTestCase + +from ..models import ( + DocumentationLink, Member, ModelReprMixin, + OffTopicChannelName, Role, SnakeName +) + + +class SimpleClass(ModelReprMixin): + def __init__(self, is_what): + self.the_cake = is_what + + +class ReprMixinTests(SimpleTestCase): + def setUp(self): + self.klass = SimpleClass('is a lie') + + def test_shows_attributes(self): + expected = "<SimpleClass(the_cake='is a lie')>" + self.assertEqual(repr(self.klass), expected) + + +class StringDunderMethodTests(SimpleTestCase): + def setUp(self): + self.objects = ( + DocumentationLink( + 'test', 'http://example.com', 'http://example.com' + ), + OffTopicChannelName(name='bob-the-builders-playground'), + SnakeName(name='python', scientific='3'), + Role( + id=5, name='test role', + colour=0x5, permissions=0 + ), + Member( + id=5, name='bob', + discriminator=1, avatar_hash=None + ) + ) + + def test_returns_string(self): + for instance in self.objects: + self.assertIsInstance(str(instance), str) |