aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/admin.py15
-rw-r--r--api/migrations/0006_add_help_texts.py44
-rw-r--r--api/models.py102
-rw-r--r--api/tests/test_models.py43
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)