diff options
Diffstat (limited to 'api')
| -rw-r--r-- | api/migrations/0031_nomination.py | 26 | ||||
| -rw-r--r-- | api/models.py | 29 | ||||
| -rw-r--r-- | api/serializers.py | 21 | ||||
| -rw-r--r-- | api/urls.py | 15 | ||||
| -rw-r--r-- | api/viewsets.py | 40 | 
5 files changed, 111 insertions, 20 deletions
diff --git a/api/migrations/0031_nomination.py b/api/migrations/0031_nomination.py new file mode 100644 index 00000000..b739d5cb --- /dev/null +++ b/api/migrations/0031_nomination.py @@ -0,0 +1,26 @@ +# Generated by Django 2.1.5 on 2019-01-27 11:01 + +import api.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0030_reminder'), +    ] + +    operations = [ +        migrations.CreateModel( +            name='Nomination', +            fields=[ +                ('active', models.BooleanField(default=True, help_text='Whether this nomination is still relevant.')), +                ('reason', models.TextField(help_text='Why this user was nominated.')), +                ('user', models.OneToOneField(help_text='The nominated user.', on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='nomination', serialize=False, to='api.User')), +                ('inserted_at', models.DateTimeField(auto_now_add=True, help_text='The creation date of this nomination.')), +                ('author', models.ForeignKey(help_text='The staff member that nominated this user.', on_delete=django.db.models.deletion.CASCADE, related_name='nomination_set', to='api.User')), +            ], +            bases=(api.models.ModelReprMixin, models.Model), +        ), +    ] diff --git a/api/models.py b/api/models.py index 5ca274ce..fa68f31c 100644 --- a/api/models.py +++ b/api/models.py @@ -408,3 +408,32 @@ class Reminder(ModelReprMixin, models.Model):      def __str__(self):          return f"{self.content} on {self.expiration} by {self.author}" + + +class Nomination(ModelReprMixin, models.Model): +    """A helper nomination created by staff.""" + +    active = models.BooleanField( +        default=True, +        help_text="Whether this nomination is still relevant." +    ) +    author = models.ForeignKey( +        User, +        on_delete=models.CASCADE, +        help_text="The staff member that nominated this user.", +        related_name='nomination_set' +    ) +    reason = models.TextField( +        help_text="Why this user was nominated." +    ) +    user = models.OneToOneField( +        User, +        on_delete=models.CASCADE, +        help_text="The nominated user.", +        primary_key=True, +        related_name='nomination' +    ) +    inserted_at = models.DateTimeField( +        auto_now_add=True, +        help_text="The creation date of this nomination." +    ) diff --git a/api/serializers.py b/api/serializers.py index fca8008f..97c4a60c 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -1,14 +1,15 @@  from rest_framework.serializers import ModelSerializer, PrimaryKeyRelatedField, ValidationError +from rest_framework.validators import UniqueValidator  from rest_framework_bulk import BulkSerializerMixin  from .models import (      DeletedMessage, DocumentationLink,      Infraction, MessageDeletionContext, -    OffTopicChannelName, Reminder, -    Role, SnakeFact, -    SnakeIdiom, SnakeName, -    SpecialSnake, Tag, -    User +    Nomination, OffTopicChannelName, +    Reminder, Role, +    SnakeFact, SnakeIdiom, +    SnakeName, SpecialSnake, +    Tag, User  ) @@ -154,3 +155,13 @@ class UserSerializer(BulkSerializerMixin, ModelSerializer):          model = User          fields = ('id', 'avatar_hash', 'name', 'discriminator', 'roles', 'in_guild')          depth = 1 + + +class NominationSerializer(ModelSerializer): +    author = PrimaryKeyRelatedField(queryset=User.objects.all()) +    user = PrimaryKeyRelatedField(queryset=User.objects.all()) + +    class Meta: +        model = Nomination +        fields = ('active', 'author', 'reason', 'user', 'inserted_at') +        depth = 1 diff --git a/api/urls.py b/api/urls.py index c8548df1..5db89e67 100644 --- a/api/urls.py +++ b/api/urls.py @@ -4,11 +4,12 @@ from rest_framework.routers import DefaultRouter  from .views import HealthcheckView, RulesView  from .viewsets import (      DeletedMessageViewSet, DocumentationLinkViewSet, -    InfractionViewSet, OffTopicChannelNameViewSet, -    ReminderViewSet, RoleViewSet, -    SnakeFactViewSet, SnakeIdiomViewSet, -    SnakeNameViewSet, SpecialSnakeViewSet, -    TagViewSet, UserViewSet +    InfractionViewSet, NominationViewSet, +    OffTopicChannelNameViewSet, ReminderViewSet, +    RoleViewSet, SnakeFactViewSet, +    SnakeIdiomViewSet, SnakeNameViewSet, +    SpecialSnakeViewSet, TagViewSet, +    UserViewSet  ) @@ -27,6 +28,10 @@ bot_router.register(      InfractionViewSet  )  bot_router.register( +    'nominations', +    NominationViewSet +) +bot_router.register(      'off-topic-channel-names',      OffTopicChannelNameViewSet,      base_name='offtopicchannelname' diff --git a/api/viewsets.py b/api/viewsets.py index 83945fe8..7ef1ba98 100644 --- a/api/viewsets.py +++ b/api/viewsets.py @@ -14,20 +14,21 @@ from rest_framework_bulk import BulkCreateModelMixin  from .models import (      DocumentationLink, Infraction, -    MessageDeletionContext, OffTopicChannelName, -    Reminder, Role, -    SnakeFact, SnakeIdiom, -    SnakeName, SpecialSnake, -    Tag, User +    MessageDeletionContext, Nomination, +    OffTopicChannelName, Reminder, +    Role, SnakeFact, +    SnakeIdiom, SnakeName, +    SpecialSnake, Tag, +    User  )  from .serializers import (      DocumentationLinkSerializer, ExpandedInfractionSerializer,      InfractionSerializer, MessageDeletionContextSerializer, -    OffTopicChannelNameSerializer, ReminderSerializer, -    RoleSerializer, SnakeFactSerializer, -    SnakeIdiomSerializer, SnakeNameSerializer, -    SpecialSnakeSerializer, TagSerializer, -    UserSerializer +    NominationSerializer, OffTopicChannelNameSerializer, +    ReminderSerializer, RoleSerializer, +    SnakeFactSerializer, SnakeIdiomSerializer, +    SnakeNameSerializer, SpecialSnakeSerializer, +    TagSerializer, UserSerializer  ) @@ -857,3 +858,22 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):      serializer_class = UserSerializer      queryset = User.objects.prefetch_related('roles') + + +class NominationViewSet(ModelViewSet): +    # TODO: doc me +    serializer_class = NominationSerializer +    queryset = Nomination.objects.prefetch_related('author', 'user') +    frozen_fields = ('author', 'inserted_at', 'user') + +    def partial_update(self, request, *args, **kwargs): +        for field in request.data: +            if field in self.frozen_fields: +                raise ValidationError({field: ['This field cannot be updated.']}) + +        instance = self.get_object() +        serializer = self.get_serializer(instance, data=request.data, partial=True) +        serializer.is_valid(raise_exception=True) +        serializer.save() + +        return Response(serializer.data)  |