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) | 
