Skip to content

Commit 25cb879

Browse files
author
Alexandra Augustine
committed
Simple Python API tutorial
1 parent 856f557 commit 25cb879

File tree

12 files changed

+184
-3
lines changed

12 files changed

+184
-3
lines changed

project/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
'django.contrib.staticfiles',
4545
'debug_toolbar',
4646
'welcome',
47+
'rest_framework',
48+
'snippets',
4749
)
4850

4951
MIDDLEWARE_CLASSES = (

project/urls.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88
# url(r'^$', 'project.views.home', name='home'),
99
# url(r'^blog/', include('blog.urls')),
1010

11-
url(r'^$', index),
12-
url(r'^health$', health),
13-
url(r'^admin/', include(admin.site.urls)),
11+
# url(r'^$', index),
12+
# url(r'^health$', health),
13+
# url(r'^admin/', include(admin.site.urls)),
14+
url(r'^', include('snippets.urls')),
15+
16+
]
17+
urlpatterns += [
18+
url(r'^api-auth/', include('rest_framework.urls',
19+
namespace='rest_framework')),
1420
]

snippets/__init__.py

Whitespace-only changes.

snippets/admin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.contrib import admin
2+
3+
# Register your models here.

snippets/migrations/0001_initial.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
from django.conf import settings
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='Snippet',
17+
fields=[
18+
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
19+
('created', models.DateTimeField(auto_now_add=True)),
20+
('title', models.CharField(default=b'', max_length=100, blank=True)),
21+
('code', models.TextField()),
22+
('linenos', models.BooleanField(default=False)),
23+
('language', models.CharField(default=b'python', max_length=100, choices=[(b'abap', b'ABAP'), (b'abnf', b'ABNF'), (b'ada', b'Ada'), (b'adl', b'ADL'), (b'agda', b'Agda'), (b'aheui', b'Aheui'), (b'ahk', b'autohotkey'), (b'alloy', b'Alloy'), (b'ampl', b'Ampl'), (b'antlr', b'ANTLR'), (b'antlr-as', b'ANTLR With ActionScript Target'), (b'antlr-cpp', b'ANTLR With CPP Target'), (b'antlr-csharp', b'ANTLR With C# Target'), (b'antlr-java', b'ANTLR With Java Target'), (b'antlr-objc', b'ANTLR With ObjectiveC Target'), (b'antlr-perl', b'ANTLR With Perl Target'), (b'antlr-python', b'ANTLR With Python Target'), (b'antlr-ruby', b'ANTLR With Ruby Target'), (b'apacheconf', b'ApacheConf'), (b'apl', b'APL'), (b'applescript', b'AppleScript'), (b'arduino', b'Arduino'), (b'as', b'ActionScript'), (b'as3', b'ActionScript 3'), (b'aspectj', b'AspectJ'), (b'aspx-cs', b'aspx-cs'), (b'aspx-vb', b'aspx-vb'), (b'asy', b'Asymptote'), (b'at', b'AmbientTalk'), (b'autoit', b'AutoIt'), (b'awk', b'Awk'), (b'basemake', b'Base Makefile'), (b'bash', b'Bash'), (b'bat', b'Batchfile'), (b'bbcode', b'BBCode'), (b'bc', b'BC'), (b'befunge', b'Befunge'), (b'bib', b'BibTeX'), (b'blitzbasic', b'BlitzBasic'), (b'blitzmax', b'BlitzMax'), (b'bnf', b'BNF'), (b'boo', b'Boo'), (b'boogie', b'Boogie'), (b'brainfuck', b'Brainfuck'), (b'bro', b'Bro'), (b'bst', b'BST'), (b'bugs', b'BUGS'), (b'c', b'C'), (b'c-objdump', b'c-objdump'), (b'ca65', b'ca65 assembler'), (b'cadl', b'cADL'), (b'camkes', b'CAmkES'), (b'capdl', b'CapDL'), (b'capnp', b"Cap'n Proto"), (b'cbmbas', b'CBM BASIC V2'), (b'ceylon', b'Ceylon'), (b'cfc', b'Coldfusion CFC'), (b'cfengine3', b'CFEngine3'), (b'cfm', b'Coldfusion HTML'), (b'cfs', b'cfstatement'), (b'chai', b'ChaiScript'), (b'chapel', b'Chapel'), (b'cheetah', b'Cheetah'), (b'cirru', b'Cirru'), (b'clay', b'Clay'), (b'clean', b'Clean'), (b'clojure', b'Clojure'), (b'clojurescript', b'ClojureScript'), (b'cmake', b'CMake'), (b'cobol', b'COBOL'), (b'cobolfree', b'COBOLFree'), (b'coffee-script', b'CoffeeScript'), (b'common-lisp', b'Common Lisp'), (b'componentpascal', b'Component Pascal'), (b'console', b'Bash Session'), (b'control', b'Debian Control file'), (b'coq', b'Coq'), (b'cpp', b'C++'), (b'cpp-objdump', b'cpp-objdump'), (b'cpsa', b'CPSA'), (b'cr', b'Crystal'), (b'crmsh', b'Crmsh'), (b'croc', b'Croc'), (b'cryptol', b'Cryptol'), (b'csharp', b'C#'), (b'csound', b'Csound Orchestra'), (b'csound-document', b'Csound Document'), (b'csound-score', b'Csound Score'), (b'css', b'CSS'), (b'css+django', b'CSS+Django/Jinja'), (b'css+erb', b'CSS+Ruby'), (b'css+genshitext', b'CSS+Genshi Text'), (b'css+lasso', b'CSS+Lasso'), (b'css+mako', b'CSS+Mako'), (b'css+mozpreproc', b'CSS+mozpreproc'), (b'css+myghty', b'CSS+Myghty'), (b'css+php', b'CSS+PHP'), (b'css+smarty', b'CSS+Smarty'), (b'cucumber', b'Gherkin'), (b'cuda', b'CUDA'), (b'cypher', b'Cypher'), (b'cython', b'Cython'), (b'd', b'D'), (b'd-objdump', b'd-objdump'), (b'dart', b'Dart'), (b'delphi', b'Delphi'), (b'dg', b'dg'), (b'diff', b'Diff'), (b'django', b'Django/Jinja'), (b'docker', b'Docker'), (b'doscon', b'MSDOS Session'), (b'dpatch', b'Darcs Patch'), (b'dtd', b'DTD'), (b'duel', b'Duel'), (b'dylan', b'Dylan'), (b'dylan-console', b'Dylan session'), (b'dylan-lid', b'DylanLID'), (b'earl-grey', b'Earl Grey'), (b'easytrieve', b'Easytrieve'), (b'ebnf', b'EBNF'), (b'ec', b'eC'), (b'ecl', b'ECL'), (b'eiffel', b'Eiffel'), (b'elixir', b'Elixir'), (b'elm', b'Elm'), (b'emacs', b'EmacsLisp'), (b'erb', b'ERB'), (b'erl', b'Erlang erl session'), (b'erlang', b'Erlang'), (b'evoque', b'Evoque'), (b'extempore', b'xtlang'), (b'ezhil', b'Ezhil'), (b'factor', b'Factor'), (b'fan', b'Fantom'), (b'fancy', b'Fancy'), (b'felix', b'Felix'), (b'fish', b'Fish'), (b'flatline', b'Flatline'), (b'forth', b'Forth'), (b'fortran', b'Fortran'), (b'fortranfixed', b'FortranFixed'), (b'foxpro', b'FoxPro'), (b'fsharp', b'FSharp'), (b'gap', b'GAP'), (b'gas', b'GAS'), (b'genshi', b'Genshi'), (b'genshitext', b'Genshi Text'), (b'glsl', b'GLSL'), (b'gnuplot', b'Gnuplot'), (b'go', b'Go'), (b'golo', b'Golo'), (b'gooddata-cl', b'GoodData-CL'), (b'gosu', b'Gosu'), (b'groff', b'Groff'), (b'groovy', b'Groovy'), (b'gst', b'Gosu Template'), (b'haml', b'Haml'), (b'handlebars', b'Handlebars'), (b'haskell', b'Haskell'), (b'haxeml', b'Hxml'), (b'hexdump', b'Hexdump'), (b'hsail', b'HSAIL'), (b'html', b'HTML'), (b'html+cheetah', b'HTML+Cheetah'), (b'html+django', b'HTML+Django/Jinja'), (b'html+evoque', b'HTML+Evoque'), (b'html+genshi', b'HTML+Genshi'), (b'html+handlebars', b'HTML+Handlebars'), (b'html+lasso', b'HTML+Lasso'), (b'html+mako', b'HTML+Mako'), (b'html+myghty', b'HTML+Myghty'), (b'html+ng2', b'HTML + Angular2'), (b'html+php', b'HTML+PHP'), (b'html+smarty', b'HTML+Smarty'), (b'html+twig', b'HTML+Twig'), (b'html+velocity', b'HTML+Velocity'), (b'http', b'HTTP'), (b'hx', b'Haxe'), (b'hybris', b'Hybris'), (b'hylang', b'Hy'), (b'i6t', b'Inform 6 template'), (b'idl', b'IDL'), (b'idris', b'Idris'), (b'iex', b'Elixir iex session'), (b'igor', b'Igor'), (b'inform6', b'Inform 6'), (b'inform7', b'Inform 7'), (b'ini', b'INI'), (b'io', b'Io'), (b'ioke', b'Ioke'), (b'irc', b'IRC logs'), (b'isabelle', b'Isabelle'), (b'j', b'J'), (b'jags', b'JAGS'), (b'jasmin', b'Jasmin'), (b'java', b'Java'), (b'javascript+mozpreproc', b'Javascript+mozpreproc'), (b'jcl', b'JCL'), (b'jlcon', b'Julia console'), (b'js', b'JavaScript'), (b'js+cheetah', b'JavaScript+Cheetah'), (b'js+django', b'JavaScript+Django/Jinja'), (b'js+erb', b'JavaScript+Ruby'), (b'js+genshitext', b'JavaScript+Genshi Text'), (b'js+lasso', b'JavaScript+Lasso'), (b'js+mako', b'JavaScript+Mako'), (b'js+myghty', b'JavaScript+Myghty'), (b'js+php', b'JavaScript+PHP'), (b'js+smarty', b'JavaScript+Smarty'), (b'jsgf', b'JSGF'), (b'json', b'JSON'), (b'json-object', b'JSONBareObject'), (b'jsonld', b'JSON-LD'), (b'jsp', b'Java Server Page'), (b'julia', b'Julia'), (b'juttle', b'Juttle'), (b'kal', b'Kal'), (b'kconfig', b'Kconfig'), (b'koka', b'Koka'), (b'kotlin', b'Kotlin'), (b'lagda', b'Literate Agda'), (b'lasso', b'Lasso'), (b'lcry', b'Literate Cryptol'), (b'lean', b'Lean'), (b'less', b'LessCss'), (b'lhs', b'Literate Haskell'), (b'lidr', b'Literate Idris'), (b'lighty', b'Lighttpd configuration file'), (b'limbo', b'Limbo'), (b'liquid', b'liquid'), (b'live-script', b'LiveScript'), (b'llvm', b'LLVM'), (b'logos', b'Logos'), (b'logtalk', b'Logtalk'), (b'lsl', b'LSL'), (b'lua', b'Lua'), (b'make', b'Makefile'), (b'mako', b'Mako'), (b'maql', b'MAQL'), (b'mask', b'Mask'), (b'mason', b'Mason'), (b'mathematica', b'Mathematica'), (b'matlab', b'Matlab'), (b'matlabsession', b'Matlab session'), (b'md', b'markdown'), (b'minid', b'MiniD'), (b'modelica', b'Modelica'), (b'modula2', b'Modula-2'), (b'monkey', b'Monkey'), (b'monte', b'Monte'), (b'moocode', b'MOOCode'), (b'moon', b'MoonScript'), (b'mozhashpreproc', b'mozhashpreproc'), (b'mozpercentpreproc', b'mozpercentpreproc'), (b'mql', b'MQL'), (b'mscgen', b'Mscgen'), (b'mupad', b'MuPAD'), (b'mxml', b'MXML'), (b'myghty', b'Myghty'), (b'mysql', b'MySQL'), (b'nasm', b'NASM'), (b'ncl', b'NCL'), (b'nemerle', b'Nemerle'), (b'nesc', b'nesC'), (b'newlisp', b'NewLisp'), (b'newspeak', b'Newspeak'), (b'ng2', b'Angular2'), (b'nginx', b'Nginx configuration file'), (b'nim', b'Nimrod'), (b'nit', b'Nit'), (b'nixos', b'Nix'), (b'nsis', b'NSIS'), (b'numpy', b'NumPy'), (b'nusmv', b'NuSMV'), (b'objdump', b'objdump'), (b'objdump-nasm', b'objdump-nasm'), (b'objective-c', b'Objective-C'), (b'objective-c++', b'Objective-C++'), (b'objective-j', b'Objective-J'), (b'ocaml', b'OCaml'), (b'octave', b'Octave'), (b'odin', b'ODIN'), (b'ooc', b'Ooc'), (b'opa', b'Opa'), (b'openedge', b'OpenEdge ABL'), (b'pacmanconf', b'PacmanConf'), (b'pan', b'Pan'), (b'parasail', b'ParaSail'), (b'pawn', b'Pawn'), (b'perl', b'Perl'), (b'perl6', b'Perl6'), (b'php', b'PHP'), (b'pig', b'Pig'), (b'pike', b'Pike'), (b'pkgconfig', b'PkgConfig'), (b'plpgsql', b'PL/pgSQL'), (b'postgresql', b'PostgreSQL SQL dialect'), (b'postscript', b'PostScript'), (b'pot', b'Gettext Catalog'), (b'pov', b'POVRay'), (b'powershell', b'PowerShell'), (b'praat', b'Praat'), (b'prolog', b'Prolog'), (b'properties', b'Properties'), (b'protobuf', b'Protocol Buffer'), (b'ps1con', b'PowerShell Session'), (b'psql', b'PostgreSQL console (psql)'), (b'pug', b'Pug'), (b'puppet', b'Puppet'), (b'py3tb', b'Python 3.0 Traceback'), (b'pycon', b'Python console session'), (b'pypylog', b'PyPy Log'), (b'pytb', b'Python Traceback'), (b'python', b'Python'), (b'python3', b'Python 3'), (b'qbasic', b'QBasic'), (b'qml', b'QML'), (b'qvto', b'QVTO'), (b'racket', b'Racket'), (b'ragel', b'Ragel'), (b'ragel-c', b'Ragel in C Host'), (b'ragel-cpp', b'Ragel in CPP Host'), (b'ragel-d', b'Ragel in D Host'), (b'ragel-em', b'Embedded Ragel'), (b'ragel-java', b'Ragel in Java Host'), (b'ragel-objc', b'Ragel in Objective C Host'), (b'ragel-ruby', b'Ragel in Ruby Host'), (b'raw', b'Raw token data'), (b'rb', b'Ruby'), (b'rbcon', b'Ruby irb session'), (b'rconsole', b'RConsole'), (b'rd', b'Rd'), (b'rebol', b'REBOL'), (b'red', b'Red'), (b'redcode', b'Redcode'), (b'registry', b'reg'), (b'resource', b'ResourceBundle'), (b'rexx', b'Rexx'), (b'rhtml', b'RHTML'), (b'rnc', b'Relax-NG Compact'), (b'roboconf-graph', b'Roboconf Graph'), (b'roboconf-instances', b'Roboconf Instances'), (b'robotframework', b'RobotFramework'), (b'rql', b'RQL'), (b'rsl', b'RSL'), (b'rst', b'reStructuredText'), (b'rts', b'TrafficScript'), (b'rust', b'Rust'), (b'sas', b'SAS'), (b'sass', b'Sass'), (b'sc', b'SuperCollider'), (b'scala', b'Scala'), (b'scaml', b'Scaml'), (b'scheme', b'Scheme'), (b'scilab', b'Scilab'), (b'scss', b'SCSS'), (b'shen', b'Shen'), (b'silver', b'Silver'), (b'slim', b'Slim'), (b'smali', b'Smali'), (b'smalltalk', b'Smalltalk'), (b'smarty', b'Smarty'), (b'sml', b'Standard ML'), (b'snobol', b'Snobol'), (b'snowball', b'Snowball'), (b'sourceslist', b'Debian Sourcelist'), (b'sp', b'SourcePawn'), (b'sparql', b'SPARQL'), (b'spec', b'RPMSpec'), (b'splus', b'S'), (b'sql', b'SQL'), (b'sqlite3', b'sqlite3con'), (b'squidconf', b'SquidConf'), (b'ssp', b'Scalate Server Page'), (b'stan', b'Stan'), (b'stata', b'Stata'), (b'swift', b'Swift'), (b'swig', b'SWIG'), (b'systemverilog', b'systemverilog'), (b'tads3', b'TADS 3'), (b'tap', b'TAP'), (b'tasm', b'TASM'), (b'tcl', b'Tcl'), (b'tcsh', b'Tcsh'), (b'tcshcon', b'Tcsh Session'), (b'tea', b'Tea'), (b'termcap', b'Termcap'), (b'terminfo', b'Terminfo'), (b'terraform', b'Terraform'), (b'tex', b'TeX'), (b'text', b'Text only'), (b'thrift', b'Thrift'), (b'todotxt', b'Todotxt'), (b'trac-wiki', b'MoinMoin/Trac Wiki markup'), (b'treetop', b'Treetop'), (b'ts', b'TypeScript'), (b'tsql', b'Transact-SQL'), (b'turtle', b'Turtle'), (b'twig', b'Twig'), (b'typoscript', b'TypoScript'), (b'typoscriptcssdata', b'TypoScriptCssData'), (b'typoscripthtmldata', b'TypoScriptHtmlData'), (b'urbiscript', b'UrbiScript'), (b'vala', b'Vala'), (b'vb.net', b'VB.net'), (b'vcl', b'VCL'), (b'vclsnippets', b'VCLSnippets'), (b'vctreestatus', b'VCTreeStatus'), (b'velocity', b'Velocity'), (b'verilog', b'verilog'), (b'vgl', b'VGL'), (b'vhdl', b'vhdl'), (b'vim', b'VimL'), (b'wdiff', b'WDiff'), (b'whiley', b'Whiley'), (b'x10', b'X10'), (b'xml', b'XML'), (b'xml+cheetah', b'XML+Cheetah'), (b'xml+django', b'XML+Django/Jinja'), (b'xml+erb', b'XML+Ruby'), (b'xml+evoque', b'XML+Evoque'), (b'xml+lasso', b'XML+Lasso'), (b'xml+mako', b'XML+Mako'), (b'xml+myghty', b'XML+Myghty'), (b'xml+php', b'XML+PHP'), (b'xml+smarty', b'XML+Smarty'), (b'xml+velocity', b'XML+Velocity'), (b'xquery', b'XQuery'), (b'xslt', b'XSLT'), (b'xtend', b'Xtend'), (b'xul+mozpreproc', b'XUL+mozpreproc'), (b'yaml', b'YAML'), (b'yaml+jinja', b'YAML+Jinja'), (b'zephir', b'Zephir')])),
24+
('style', models.CharField(default=b'friendly', max_length=100, choices=[(b'abap', b'abap'), (b'algol', b'algol'), (b'algol_nu', b'algol_nu'), (b'arduino', b'arduino'), (b'autumn', b'autumn'), (b'borland', b'borland'), (b'bw', b'bw'), (b'colorful', b'colorful'), (b'default', b'default'), (b'emacs', b'emacs'), (b'friendly', b'friendly'), (b'fruity', b'fruity'), (b'igor', b'igor'), (b'lovelace', b'lovelace'), (b'manni', b'manni'), (b'monokai', b'monokai'), (b'murphy', b'murphy'), (b'native', b'native'), (b'paraiso-dark', b'paraiso-dark'), (b'paraiso-light', b'paraiso-light'), (b'pastie', b'pastie'), (b'perldoc', b'perldoc'), (b'rainbow_dash', b'rainbow_dash'), (b'rrt', b'rrt'), (b'tango', b'tango'), (b'trac', b'trac'), (b'vim', b'vim'), (b'vs', b'vs'), (b'xcode', b'xcode')])),
25+
('highlighted', models.TextField()),
26+
('owner', models.ForeignKey(related_name='snippets', to=settings.AUTH_USER_MODEL)),
27+
],
28+
options={
29+
'ordering': ('created',),
30+
},
31+
),
32+
]

snippets/migrations/__init__.py

Whitespace-only changes.

snippets/models.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from django.db import models
2+
from pygments.lexers import get_all_lexers
3+
from pygments.styles import get_all_styles
4+
from pygments.lexers import get_lexer_by_name
5+
from pygments.formatters.html import HtmlFormatter
6+
from pygments import highlight
7+
8+
LEXERS = [item for item in get_all_lexers() if item[1]]
9+
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
10+
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
11+
12+
class Snippet(models.Model):
13+
created = models.DateTimeField(auto_now_add=True)
14+
title = models.CharField(max_length=100, blank=True, default='')
15+
code = models.TextField()
16+
linenos = models.BooleanField(default=False)
17+
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
18+
style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
19+
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
20+
highlighted = models.TextField()
21+
22+
class Meta:
23+
ordering = ('created',)
24+
def save(self, *args, **kwargs):
25+
"""
26+
Use the `pygments` library to create a highlighted HTML
27+
representation of the code snippet.
28+
"""
29+
lexer = get_lexer_by_name(self.language)
30+
linenos = self.linenos and 'table' or False
31+
options = self.title and {'title': self.title} or {}
32+
formatter = HtmlFormatter(style=self.style, linenos=linenos, full=True, **options)
33+
self.highlighted = highlight(self.code, lexer, formatter)
34+
super(Snippet, self).save(*args, **kwargs)
35+

snippets/permissions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from rest_framework import permissions
2+
3+
4+
class IsOwnerOrReadOnly(permissions.BasePermission):
5+
"""
6+
Custom permission to only allow owners of an object to edit it.
7+
"""
8+
9+
def has_object_permission(self, request, view, obj):
10+
# Read permissions are allowed to any request,
11+
# so we'll always allow GET, HEAD or OPTIONS requests.
12+
if request.method in permissions.SAFE_METHODS:
13+
return True
14+
15+
# Write permissions are only allowed to the owner of the snippet.
16+
return obj.owner == request.user

snippets/serializers.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from rest_framework import serializers
2+
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
3+
from django.contrib.auth.models import User
4+
5+
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
6+
owner = serializers.ReadOnlyField(source='owner.username')
7+
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
8+
9+
class Meta:
10+
model = Snippet
11+
fields = ('url', 'id', 'highlight', 'owner',
12+
'title', 'code', 'linenos', 'language', 'style')
13+
14+
class UserSerializer(serializers.HyperlinkedModelSerializer):
15+
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)
16+
17+
class Meta:
18+
model = User
19+
fields = ('url', 'id', 'username', 'snippets')

snippets/tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.test import TestCase
2+
3+
# Create your tests here.

snippets/urls.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from django.conf.urls import url, include
2+
from snippets import views
3+
from rest_framework.routers import DefaultRouter
4+
from rest_framework.schemas import get_schema_view
5+
6+
schema_view = get_schema_view(title='Pastebin API')
7+
# Create a router and register our viewsets with it.
8+
router = DefaultRouter()
9+
router.register(r'snippets', views.SnippetViewSet)
10+
router.register(r'users', views.UserViewSet)
11+
12+
# The API URLs are now determined automatically by the router.
13+
# Additionally, we include the login URLs for the browsable API.
14+
urlpatterns = [
15+
url('^schema/$', schema_view),
16+
url(r'^', include(router.urls)),
17+
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
18+
]

snippets/views.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from snippets.models import Snippet
2+
from snippets.serializers import SnippetSerializer
3+
from snippets.serializers import UserSerializer
4+
from snippets.permissions import IsOwnerOrReadOnly
5+
from django.contrib.auth.models import User
6+
from rest_framework import generics
7+
from rest_framework import permissions
8+
from rest_framework import renderers
9+
from rest_framework import viewsets
10+
from rest_framework.decorators import api_view
11+
from rest_framework.response import Response
12+
from rest_framework.reverse import reverse
13+
from rest_framework.decorators import detail_route
14+
15+
class SnippetViewSet(viewsets.ModelViewSet):
16+
"""
17+
This viewset automatically provides `list`, `create`, `retrieve`,
18+
`update` and `destroy` actions.
19+
20+
Additionally we also provide an extra `highlight` action.
21+
"""
22+
queryset = Snippet.objects.all()
23+
serializer_class = SnippetSerializer
24+
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
25+
IsOwnerOrReadOnly,)
26+
27+
@detail_route(renderer_classes=[renderers.StaticHTMLRenderer])
28+
def highlight(self, request, *args, **kwargs):
29+
snippet = self.get_object()
30+
return Response(snippet.highlighted)
31+
32+
def perform_create(self, serializer):
33+
serializer.save(owner=self.request.user)
34+
35+
class UserViewSet(viewsets.ReadOnlyModelViewSet):
36+
"""
37+
This viewset automatically provides `list` and `detail` actions.
38+
"""
39+
queryset = User.objects.all()
40+
serializer_class = UserSerializer
41+
42+
@api_view(['GET'])
43+
def api_root(request, format=None):
44+
return Response({
45+
'users': reverse('user-list', request=request, format=format),
46+
'snippets': reverse('snippet-list', request=request, format=format)
47+
})

0 commit comments

Comments
 (0)