PK!H..mb_drf_article/__init__.py"""Article init.""" __version__ = '0.1.0' PK!S#mb_drf_article/admin.py"""Article admin.""" from django.contrib import admin from .models import Article, Category # Register your models here. admin.site.register(Article) admin.site.register(Category) PK!eemb_drf_article/apps.pyfrom django.apps import AppConfig class ArticleConfig(AppConfig): name = 'mb_drf_article' PK!ꗩ)mb_drf_article/migrations/0001_initial.py# Generated by Django 2.2.2 on 2019-06-11 18:37 from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=50)), ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='article.Category')), ], options={ 'verbose_name_plural': 'categories', }, ), migrations.CreateModel( name='Article', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=50)), ('tldr', models.CharField(max_length=80)), ('content', models.TextField()), ('image', models.ImageField(upload_to='article_header')), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('categories', models.ManyToManyField(to='article.Category')), ], ), ] PK!M>AA4mb_drf_article/migrations/0002_auto_20190612_1341.py# Generated by Django 2.2.2 on 2019-06-12 11:41 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('article', '0001_initial'), ] operations = [ migrations.AddField( model_name='article', name='slug_title', field=models.SlugField(default='', unique=True), ), migrations.AlterField( model_name='article', name='title', field=models.CharField(max_length=50, unique=True), ), ] PK!A|4mb_drf_article/migrations/0003_auto_20190612_1343.py# Generated by Django 2.2.2 on 2019-06-12 11:43 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('article', '0002_auto_20190612_1341'), ] operations = [ migrations.AlterField( model_name='article', name='slug_title', field=models.SlugField(unique=True), ), ] PK!%mb_drf_article/migrations/__init__.pyPK!rmb_drf_article/models.py"""Articles models.""" from django.db import models from django.template.defaultfilters import slugify # Create your models here. class Category(models.Model): """Category class.""" name = models.CharField(max_length=50) parent = models.ForeignKey('self', on_delete=models.CASCADE) def __str__(self): """Category print.""" return self.name class Meta: """Category meta.""" verbose_name_plural = "categories" class Article(models.Model): """Article class.""" title = models.CharField(max_length=50, unique=True) slug_title = models.SlugField(unique=True) tldr = models.CharField(max_length=80) content = models.TextField() image = models.ImageField(upload_to='article_header') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) categories = models.ManyToManyField(to=Category) def __str__(self): """Representation.""" return self.title def save(self, *args, **kwargs): """Slugify the title before save.""" self.slug_title = slugify(self.title) super(Article, self).save(*args, **kwargs) PK!Cmmb_drf_article/permissions.py"""Article permissions.""" from rest_framework.permissions import IsAdminUser, SAFE_METHODS class IsAdminUserOrReadOnly(IsAdminUser): """From https://stackoverflow.com. slug title: django-rest-framework-permission-isadminorreadonly """ def has_permission(self, request, view): """Permission method.""" is_admin = super().has_permission(request, view) return request.method in SAFE_METHODS or is_admin PK!!?mb_drf_article/serializers.py"""Article serializer.""" from rest_framework import serializers from .models import Article # , Category class ArticleSerializer(serializers.ModelSerializer): """Serializer.""" class Meta: """Article meta serializer.""" model = Article fields = ('id', 'title', 'tldr', 'content', 'image', 'created_at', 'updated_at', 'slug_title') read_only_fields = ('id', 'created_at', 'updated_at', 'slug_title') lookup_field = 'slug_title' PK!B??mb_drf_article/tests.pyfrom django.test import TestCase # Create your tests here. PK!4-55mb_drf_article/urls.py"""Articles urls.""" from django.urls import path from rest_framework.urlpatterns import format_suffix_patterns from . import views urlpatterns = [ path('', views.ArticleList.as_view()), path('', views.ArticleDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) PK!mb_drf_article/views.py"""Article views.""" from rest_framework import generics from .serializers import ArticleSerializer from .permissions import IsAdminUserOrReadOnly from .models import Article class ArticleList(generics.ListCreateAPIView): """Article list view.""" queryset = Article.objects.all().order_by('-created_at') serializer_class = ArticleSerializer permission_classes = (IsAdminUserOrReadOnly,) class ArticleDetail(generics.RetrieveUpdateDestroyAPIView): """Article detail view.""" queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = (IsAdminUserOrReadOnly,) lookup_field = ('slug_title') PK!HڽTU$mb_drf_article-0.1.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!HNhC'mb_drf_article-0.1.0.dist-info/METADATAUQo6~8Jn+u;Q%,6 6-6dI*PhnmSxw<^r X++VyXEȌ=HZ%3uJU5,g&*psten)P%5["9m^o)ܪ\wpw/%ȹf#[nbWWn D257Bmdb7lrsKoȄF5xJvI8[3kBp2w(Yr ox`_ꄞ`C,xqU.s;VtFݡ+~槺`1ua\\BZ[\{06jG-C3Kg@xo[#SZKg$o:we#u%+r|8b>܅ד$ L}Es^pfƛWû~[$@ ,0Ը5i N+ 8Rdߕo:8#E{  ̆Wi'ɠ?t;߄lfv i{PJIЎtqB*8Հ)ϕ\ݔfYh.!ڭ_ B(]?z z˖&g^v*ۃ>9ËK&,(EY8ҋAІ5kFǫK$n`xꥐw!mgQ߷fs <<T%ufI|9M>b=HwI6Wq6]Mϒ8MO9AyOe/HD)hlkŀi:gސM PK!HmOL%mb_drf_article-0.1.0.dist-info/RECORDrHE-`X$@! (S`=3![8f捬(J*EACt _"82|ܳB%oV}"34 NUFMr&ixlE.(;I-@͆$7L":@sc2rS|}w y֮r=PWfGzn,d53\RiìcD#tmYV+CO606b(Zhd `GCI6X{:]Knulb] S7B1KYкh:֍RM@pO QTm3 ^$opSּev#Ι f!Q68>oO`_#}md|B9 APK!H..mb_drf_article/__init__.pyPK!S#fmb_drf_article/admin.pyPK!ee]mb_drf_article/apps.pyPK!ꗩ)mb_drf_article/migrations/0001_initial.pyPK!M>AA4mb_drf_article/migrations/0002_auto_20190612_1341.pyPK!A|4y mb_drf_article/migrations/0003_auto_20190612_1343.pyPK!%b mb_drf_article/migrations/__init__.pyPK!r mb_drf_article/models.pyPK!Cmmb_drf_article/permissions.pyPK!!?mb_drf_article/serializers.pyPK!B??mb_drf_article/tests.pyPK!4-55Kmb_drf_article/urls.pyPK!mb_drf_article/views.pyPK!HڽTU$mb_drf_article-0.1.0.dist-info/WHEELPK!HNhC'/mb_drf_article-0.1.0.dist-info/METADATAPK!HmOL%mb_drf_article-0.1.0.dist-info/RECORDPK!