Skip to content

Commit

Permalink
ft(escalating): add feature to report article
Browse files Browse the repository at this point in the history
- add model for reported articles
- add serializer for reported articles
- add view to report articles
- add  url to report articles

[DELIVERS #160617687]

ft(escalating): correct migrations

-correct migrations

[FIXES #160617687]

ft(escalating): escalations

- add admin access

[DELIVERS #160617687]

ft(escalating): escalations

- add times article
- add report article serializer
- add report article urls
- add report view
- add migrations
- add tests for the feature

[DELIVERS #160617687]
  • Loading branch information
kimbugp committed Oct 19, 2018
1 parent c98fb27 commit d371b81
Show file tree
Hide file tree
Showing 18 changed files with 400 additions and 107 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,23 @@ No additional parameters required

`GET /api/tags`

### Report an article

`POST /api/articles/:slug/report/`

Authentication and reason for reporting required
Request Body
```source-json
{
"report": {
"reason": "this is not the best tense to use"
}
}
```






6 changes: 5 additions & 1 deletion authors/apps/articles/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from django.contrib import admin
from authors.apps.articles.models import Article, RateArticle, LikeArticle, Category

from authors.apps.articles.models import (Article, Category, LikeArticle,
RateArticle, Reported)

admin.site.register(Article)
admin.site.register(RateArticle)
admin.site.register(LikeArticle)
admin.site.register(Category)
admin.site.register(Reported)
25 changes: 25 additions & 0 deletions authors/apps/articles/migrations/0006_reported.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 2.1.1 on 2018-10-17 16:57

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0005_merge_20181016_2114'),
]

operations = [
migrations.CreateModel(
name='Reported',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('reason', models.TextField()),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='articles.Article', to_field='slug')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, to_field='email')),
],
),
]
20 changes: 20 additions & 0 deletions authors/apps/articles/migrations/0007_reported_created_at.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 2.1.1 on 2018-10-18 07:30

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('articles', '0006_reported'),
]

operations = [
migrations.AddField(
model_name='reported',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
]
17 changes: 17 additions & 0 deletions authors/apps/articles/migrations/0008_auto_20181018_1517.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 2.1.1 on 2018-10-18 12:17

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('articles', '0007_reported_created_at'),
]

operations = [
migrations.AlterModelOptions(
name='reported',
options={'ordering': ['-created_at']},
),
]
18 changes: 18 additions & 0 deletions authors/apps/articles/migrations/0009_reported_times_reported.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.1.1 on 2018-10-18 13:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('articles', '0008_auto_20181018_1517'),
]

operations = [
migrations.AddField(
model_name='reported',
name='times_reported',
field=models.IntegerField(default=0),
),
]
18 changes: 18 additions & 0 deletions authors/apps/articles/migrations/0010_article_times_reported.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.1.1 on 2018-10-18 13:43

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('articles', '0009_reported_times_reported'),
]

operations = [
migrations.AddField(
model_name='article',
name='times_reported',
field=models.IntegerField(default=0),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 2.1.1 on 2018-10-18 13:53

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('articles', '0010_article_times_reported'),
]

operations = [
migrations.RemoveField(
model_name='reported',
name='times_reported',
),
]
21 changes: 18 additions & 3 deletions authors/apps/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from django.db.models import Avg, Count
from django.utils import timezone
from django.utils.text import slugify
from taggit.managers import TaggableManager

from authors.apps.authentication.models import User
from authors.apps.profiles.models import Profile
from taggit.managers import TaggableManager

from .utils import get_unique_slug, time

Expand All @@ -15,7 +16,7 @@ class Category(models.Model):
title = models.CharField(max_length=100, default="general")
slug = models.SlugField(max_length=100, unique=True)

class Meta:
class Meta:
verbose_name_plural = "Categories"

def __str__(self):
Expand Down Expand Up @@ -57,8 +58,9 @@ class Article(models.Model):

tags = TaggableManager()

category = models.ForeignKey(Category,
category = models.ForeignKey(Category,
on_delete=models.CASCADE)
times_reported = models.IntegerField(default=0)

def __str__(self):
"""
Expand Down Expand Up @@ -116,3 +118,16 @@ class LikeArticle(models.Model):
article = models.ForeignKey(Article, blank=False, on_delete=models.CASCADE)

likes = models.NullBooleanField()


class Reported(models.Model):
article = models.ForeignKey(
Article, blank=False, on_delete=models.CASCADE, to_field='slug')
user = models.ForeignKey(
User, blank=False, on_delete=models.CASCADE, to_field='email')
reason = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)


class Meta:
ordering = ['-created_at']
4 changes: 4 additions & 0 deletions authors/apps/articles/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class CategoryJSONRenderer(AhJSONRenderer):
charset = 'utf-8'
object_label = 'category'

class ReportArticleJSONRenderer(AhJSONRenderer):
charset = 'utf-8'
object_label = 'support'


class ShareArticleJSONRenderer(AhJSONRenderer):
charset = 'utf-8'
Expand Down
43 changes: 31 additions & 12 deletions authors/apps/articles/serializers.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
from authors.apps.articles.models import Article, RateArticle, LikeArticle, Category
from authors.apps.authentication.models import User
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers
from taggit_serializer.serializers import (TagListSerializerField,
TaggitSerializer)


from authors.apps.articles.models import (Article, Category, LikeArticle,
RateArticle, Reported)
from authors.apps.authentication.models import User
from taggit.models import Tag
from taggit_serializer.serializers import (TaggitSerializer,
TagListSerializerField)


class ArticleSerializer(TaggitSerializer, serializers.ModelSerializer):
"""Serializer for articles."""
author = serializers.ReadOnlyField(source='author.username')
read_time = serializers.ReadOnlyField(source='read')
tags = TagListSerializerField()

class Meta:
model = Article
""" List all of the fields that could possibly be included in a request
or response, including fields specified explicitly above."""

fields = (
'author', 'title', 'slug', 'description', 'body', 'created_at',
'updated_at', 'read_time', 'average_rating', 'likes', 'dislikes',
'author', 'title', 'slug', 'description', 'body', 'created_at',
'updated_at', 'read_time', 'average_rating', 'likes', 'dislikes',
'tags', 'category', 'favorites_count', 'image')
read_only_fields = ('slug', 'author_id',)


class TagSerializer(serializers.ModelSerializer):

class Meta:
model = Tag
fields = ('name',)


class CategorySerializer(serializers.ModelSerializer):


class Meta:
model = Category
fields = ('id', 'title', 'slug')
read_only_fields = ('id', 'slug',)


class RateArticleSerializer(serializers.ModelSerializer):
rated_by = serializers.ReadOnlyField(source='rated_by.username')
article = serializers.ReadOnlyField(source='article.slug')
Expand Down Expand Up @@ -79,7 +81,6 @@ def validate(self, data):
return {
"likes": likes}


def get_favorites_count(self, instance):
return instance.favorited_by.count()

Expand All @@ -94,3 +95,21 @@ def check(self, data):
raise serializers.ValidationError(
'An email is required to share.'
)
class ReportArticleSerializer(serializers.ModelSerializer):
article_title = serializers.ReadOnlyField(source='article.title')
article_slug = serializers.ReadOnlyField(source='article.slug')
article_author = serializers.ReadOnlyField(source='article.author.email')
reported_by = serializers.ReadOnlyField(source='user.email')

class Meta:
model = Reported
fields = ['article_title', 'reason', 'article_slug',
'article_author', 'reported_by']

class ReportSerializer(ReportArticleSerializer):
times_reported = serializers.ReadOnlyField(source='article.times_reported')

class Meta:
model = Reported
fields = ['article_title','article_slug',
'article_author','times_reported','reason']
22 changes: 14 additions & 8 deletions authors/apps/articles/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from django.urls import path

from .views import (
ArticleAPIView, ArticleAPIDetailsView,
RateArticleView, LikeArticleView, LikeAPIDetailsView,
TagListAPIView, TagRetrieveAPIView, CategoryListCreateAPIView,
CategoryRetrieveAPIView, FavoriteArticleView, UnFavoriteArticleView,
ShareArticleAPIView,)
from .views import (ArticleAPIDetailsView, ArticleAPIView,
CategoryListCreateAPIView, CategoryRetrieveAPIView,
FavoriteArticleView, LikeAPIDetailsView, LikeArticleView,
RateArticleView, ReportArticle, ReportArticleListView,
ReportView, ShareArticleAPIView, TagListAPIView,
TagRetrieveAPIView, UnFavoriteArticleView)

app_name = "articles"

Expand All @@ -24,8 +24,14 @@
path("tags/<str:tag_name>/", TagRetrieveAPIView.as_view()),
path("categories/", CategoryListCreateAPIView.as_view()),
path("categories/<str:cat_name>/", CategoryRetrieveAPIView.as_view()),
path('articles/<str:slug>/favorite/', FavoriteArticleView.as_view(), name="favorite"),
path('articles/<str:slug>/unfavorite/', UnFavoriteArticleView.as_view(), name="unfavorite")
path('articles/<str:slug>/favorite/',
FavoriteArticleView.as_view(), name="favorite"),
path('articles/<str:slug>/unfavorite/',
UnFavoriteArticleView.as_view(), name="unfavorite"),
path('articles/<str:slug>/report/', ReportArticle.as_view(), name="escalate"),
path('escalations/', ReportArticleListView.as_view(), name="escalated"),
path('escalations/report/', ReportView.as_view(), name="escalatation report")



]
Loading

0 comments on commit d371b81

Please sign in to comment.