Improve RelatedField and callable default handling

- callable default values will now be properly called 
  - PrimaryKeyRelatedField and SlugRelatedField will now return an appropriate type based on the relation model's Field
  - mock views now have a request object bound even when public is True
This commit is contained in:
Cristi Vîjdea
2017-12-23 11:52:31 +01:00
parent f05889292a
commit 9f6ee4da87
17 changed files with 274 additions and 142 deletions
+8 -4
View File
@@ -1,6 +1,8 @@
# Generated by Django 2.0 on 2017-12-05 04:05
# Generated by Django 2.0 on 2017-12-23 09:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
@@ -8,6 +10,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
@@ -15,12 +18,13 @@ class Migration(migrations.Migration):
name='Article',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(help_text='Main article headline', max_length=255, unique=True)),
('body', models.TextField(help_text='Article content', max_length=5000)),
('slug', models.SlugField(blank=True, help_text='Unique URL slug identifying the article', unique=True)),
('title', models.CharField(help_text='title model help_text', max_length=255, unique=True)),
('body', models.TextField(help_text='article model help_text', max_length=5000)),
('slug', models.SlugField(blank=True, help_text='slug model help_text', unique=True)),
('date_created', models.DateTimeField(auto_now_add=True)),
('date_modified', models.DateTimeField(auto_now=True)),
('cover', models.ImageField(blank=True, upload_to='article/original/')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to=settings.AUTH_USER_MODEL)),
],
),
]
@@ -1,28 +0,0 @@
# Generated by Django 2.0 on 2017-12-21 15:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('articles', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='article',
name='body',
field=models.TextField(help_text='article model help_text', max_length=5000),
),
migrations.AlterField(
model_name='article',
name='slug',
field=models.SlugField(blank=True, help_text='slug model help_text', unique=True),
),
migrations.AlterField(
model_name='article',
name='title',
field=models.CharField(help_text='title model help_text', max_length=255, unique=True),
),
]
+1
View File
@@ -7,5 +7,6 @@ class Article(models.Model):
slug = models.SlugField(help_text="slug model help_text", unique=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
author = models.ForeignKey('auth.User', related_name='articles', on_delete=models.CASCADE)
cover = models.ImageField(upload_to='article/original/', blank=True)
+9 -2
View File
@@ -14,12 +14,19 @@ class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ('title', 'body', 'slug', 'date_created', 'date_modified',
fields = ('title', 'author', 'body', 'slug', 'date_created', 'date_modified',
'references', 'uuid', 'cover', 'cover_name')
read_only_fields = ('date_created', 'date_modified',
'references', 'uuid', 'cover_name')
lookup_field = 'slug'
extra_kwargs = {'body': {'help_text': 'body serializer help_text'}}
extra_kwargs = {
'body': {'help_text': 'body serializer help_text'},
'author': {
'default': serializers.CurrentUserDefault(),
'help_text': "The ID of the user that created this article; if none is provided, "
"defaults to the currently logged in user."
},
}
class ImageUploadSerializer(serializers.Serializer):
+6 -2
View File
@@ -20,6 +20,11 @@ class NoPagingAutoSchema(SwaggerAutoSchema):
return False
class ArticlePagination(LimitOffsetPagination):
default_limit = 5
max_limit = 25
@method_decorator(name='list', decorator=swagger_auto_schema(
operation_description="description from swagger_auto_schema via method_decorator"
))
@@ -41,8 +46,7 @@ class ArticleViewSet(viewsets.ModelViewSet):
lookup_value_regex = r'[a-z0-9]+(?:-[a-z0-9]+)'
serializer_class = serializers.ArticleSerializer
pagination_class = LimitOffsetPagination
max_page_size = 5
pagination_class = ArticlePagination
filter_backends = (DjangoFilterBackend, OrderingFilter)
filter_fields = ('title',)
ordering_fields = ('date_modified','date_created')
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1,27 +0,0 @@
# Generated by Django 2.0 on 2017-12-05 04:05
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),
('snippets', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='snippet',
name='owner',
field=models.ForeignKey(default='', on_delete=django.db.models.deletion.CASCADE, related_name='snippets', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
migrations.AlterField(
model_name='snippet',
name='code',
field=models.TextField(help_text='code model help text'),
),
]
+16 -2
View File
@@ -1,3 +1,4 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
@@ -23,7 +24,18 @@ class SnippetSerializer(serializers.Serializer):
create: docstring for create from serializer classdoc
"""
id = serializers.IntegerField(read_only=True, help_text="id serializer help text")
owner = serializers.ReadOnlyField(source='owner.username')
owner = serializers.PrimaryKeyRelatedField(
queryset=get_user_model().objects.all(),
default=serializers.CurrentUserDefault(),
help_text="The ID of the user that created this snippet; if none is provided, "
"defaults to the currently logged in user."
)
owner_as_string = serializers.PrimaryKeyRelatedField(
help_text="The ID of the user that created this snippet.",
pk_field=serializers.CharField(help_text="this help text should not show up"),
read_only=True,
source='owner',
)
title = serializers.CharField(required=False, allow_blank=True, max_length=100)
code = serializers.CharField(style={'base_template': 'textarea.html'})
linenos = serializers.BooleanField(required=False)
@@ -31,7 +43,8 @@ class SnippetSerializer(serializers.Serializer):
styles = serializers.MultipleChoiceField(choices=STYLE_CHOICES, default=['friendly'])
lines = serializers.ListField(child=serializers.IntegerField(), allow_empty=True, allow_null=True, required=False)
example_projects = serializers.ListSerializer(child=ExampleProjectSerializer(), read_only=True)
difficulty_factor = serializers.FloatField(help_text="this is here just to test FloatField", read_only=True)
difficulty_factor = serializers.FloatField(help_text="this is here just to test FloatField",
read_only=True, default=lambda: 6.9)
def create(self, validated_data):
"""
@@ -39,6 +52,7 @@ class SnippetSerializer(serializers.Serializer):
"""
del validated_data['styles']
del validated_data['lines']
del validated_data['difficulty_factor']
return Snippet.objects.create(**validated_data)
def update(self, instance, validated_data):
+6 -3
View File
@@ -1,19 +1,22 @@
from django.contrib.auth.models import User
from rest_framework import serializers
from articles.models import Article
from snippets.models import Snippet
class UserSerializerrr(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
article_slugs = serializers.SlugRelatedField(read_only=True, slug_field='slug', many=True, source='articlessss')
last_connected_ip = serializers.IPAddressField(help_text="i'm out of ideas", protocol='ipv4', read_only=True)
last_connected_at = serializers.DateField(help_text="really?", read_only=True)
class Meta:
model = User
fields = ('id', 'username', 'email', 'snippets', 'last_connected_ip', 'last_connected_at')
fields = ('id', 'username', 'email', 'articles', 'snippets',
'last_connected_ip', 'last_connected_at', 'article_slugs')
class UserListQuerySerializer(serializers.Serializer):
username = serializers.CharField(help_text="this field is generated from a query_serializer")
is_staff = serializers.BooleanField(help_text="this one too!")
username = serializers.CharField(help_text="this field is generated from a query_serializer", required=False)
is_staff = serializers.BooleanField(help_text="this one too!", required=False)