Skip to content

Commit a64bc9e

Browse files
committed
Release v1.0.1 - Implements API GENERATOR
1 parent d148eb4 commit a64bc9e

File tree

15 files changed

+278
-6
lines changed

15 files changed

+278
-6
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change Log
22

3+
## [1.0.1] 2022-10-22
4+
### Improvements
5+
6+
- Implements the [Django API Generator](https://github.com/app-generator/django-api-generator)
7+
38
## [1.0.0] 2022-10-20
49
### Initial Release
510

README.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
# Django Core
1+
# [Django API Generator](https://github.com/app-generator/django-api-generator) `Sample`
22

33
Minimal **Django** project with `Docker` support - actively supported by [AppSeed](https://appseed.us/) via `Email` and `Discord`.
44

5-
> Features:
5+
> Features - see **[video](https://www.youtube.com/watch?v=fkjvhFejEv8)** presentation
66
77
-`Up-to-date Dependencies`
88
-`Docker`
9+
- ✅ Integrates [API Generator](https://github.com/app-generator/django-api-generator) Library for Django
10+
911

1012
<br />
1113

@@ -48,7 +50,6 @@ $ virtualenv env
4850
$ source env/bin/activate
4951
$ pip install -r requirements.txt
5052
```
51-
5253
<br />
5354

5455
> 👉 Set Up Database
@@ -60,15 +61,35 @@ $ python manage.py migrate
6061

6162
<br />
6263

64+
> 👉 Create SuperUser
65+
66+
```bash
67+
$ python manage.py createsuperuser
68+
```
69+
70+
<br />
71+
72+
> 👉 Generate the API for `Books` model
73+
74+
```bash
75+
$ python manage.py generate-api
76+
```
77+
78+
<br />
79+
6380
> 👉 Start the app
6481
6582
```bash
6683
$ python manage.py runserver
6784
```
6885

69-
At this point, the app runs at `http://127.0.0.1:8000/`.
86+
At this point, the app runs at `http://127.0.0.1:8000/` and the API is usable `http://127.0.0.1:8000/api/books/`
87+
88+
<br />
89+
90+
![Django API Generator - DRF Interface (open-source tool).](https://user-images.githubusercontent.com/51070104/197181145-f7458df7-23c3-4c14-bcb1-8e168882a104.jpg)
7091

7192
<br />
7293

7394
---
74-
**Django Core** - Minimal **Django** core provided by **[AppSeed](https://appseed.us/)**
95+
[Django API Generator](https://github.com/app-generator/django-api-generator) `Sampl` - Minimal **Django** starter provided by **[AppSeed](https://appseed.us/)**

api/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# -*- encoding: utf-8 -*-
2+
"""
3+
Copyright (c) 2019 - present AppSeed.us
4+
"""

api/serializers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from rest_framework import serializers
2+
3+
4+
from app1.models import Book
5+
6+
from app1.models import City
7+
8+
9+
10+
class BookSerializer(serializers.ModelSerializer):
11+
class Meta:
12+
model = Book
13+
fields = '__all__'
14+
15+
16+
class CitySerializer(serializers.ModelSerializer):
17+
class Meta:
18+
model = City
19+
fields = '__all__'
20+

api/urls.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.urls import re_path
2+
from django.views.decorators.csrf import csrf_exempt
3+
4+
from api.views import *
5+
6+
7+
urlpatterns = [
8+
9+
re_path("books/((?P<pk>\d+)/)?", csrf_exempt(BookView.as_view())),
10+
re_path("cities/((?P<pk>\d+)/)?", csrf_exempt(CityView.as_view())),
11+
12+
]

api/views.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from http import HTTPStatus
2+
from django.http import Http404
3+
from rest_framework.response import Response
4+
from rest_framework.views import APIView
5+
from rest_framework.generics import get_object_or_404
6+
from rest_framework.permissions import IsAuthenticatedOrReadOnly
7+
8+
9+
from api.serializers import *
10+
11+
12+
from app1.models import Book
13+
14+
from app1.models import City
15+
16+
17+
18+
class BookView(APIView):
19+
20+
permission_classes = (IsAuthenticatedOrReadOnly,)
21+
22+
def post(self, request):
23+
serializer = BookSerializer(data=request.POST)
24+
if not serializer.is_valid():
25+
return Response(data={
26+
**serializer.errors,
27+
'success': False
28+
}, status=HTTPStatus.BAD_REQUEST)
29+
serializer.save()
30+
return Response(data={
31+
'message': 'Record Created.',
32+
'success': True
33+
}, status=HTTPStatus.OK)
34+
35+
def get(self, request, pk=None):
36+
if not pk:
37+
return Response({
38+
'data': [BookSerializer(instance=obj).data for obj in Book.objects.all()],
39+
'success': True
40+
}, status=HTTPStatus.OK)
41+
try:
42+
obj = get_object_or_404(Book, pk=pk)
43+
except Http404:
44+
return Response(data={
45+
'message': 'object with given id not found.',
46+
'success': False
47+
}, status=HTTPStatus.NOT_FOUND)
48+
return Response({
49+
'data': BookSerializer(instance=obj).data,
50+
'success': True
51+
}, status=HTTPStatus.OK)
52+
53+
def put(self, request, pk):
54+
try:
55+
obj = get_object_or_404(Book, pk=pk)
56+
except Http404:
57+
return Response(data={
58+
'message': 'object with given id not found.',
59+
'success': False
60+
}, status=HTTPStatus.NOT_FOUND)
61+
serializer = BookSerializer(instance=obj, data=request.POST, partial=True)
62+
if not serializer.is_valid():
63+
return Response(data={
64+
**serializer.errors,
65+
'success': False
66+
}, status=HTTPStatus.BAD_REQUEST)
67+
serializer.save()
68+
return Response(data={
69+
'message': 'Record Updated.',
70+
'success': True
71+
}, status=HTTPStatus.OK)
72+
73+
def delete(self, request, pk):
74+
try:
75+
obj = get_object_or_404(Book, pk=pk)
76+
except Http404:
77+
return Response(data={
78+
'message': 'object with given id not found.',
79+
'success': False
80+
}, status=HTTPStatus.NOT_FOUND)
81+
obj.delete()
82+
return Response(data={
83+
'message': 'Record Deleted.',
84+
'success': True
85+
}, status=HTTPStatus.OK)
86+
87+
88+
class CityView(APIView):
89+
90+
permission_classes = (IsAuthenticatedOrReadOnly,)
91+
92+
def post(self, request):
93+
serializer = CitySerializer(data=request.POST)
94+
if not serializer.is_valid():
95+
return Response(data={
96+
**serializer.errors,
97+
'success': False
98+
}, status=HTTPStatus.BAD_REQUEST)
99+
serializer.save()
100+
return Response(data={
101+
'message': 'Record Created.',
102+
'success': True
103+
}, status=HTTPStatus.OK)
104+
105+
def get(self, request, pk=None):
106+
if not pk:
107+
return Response({
108+
'data': [CitySerializer(instance=obj).data for obj in City.objects.all()],
109+
'success': True
110+
}, status=HTTPStatus.OK)
111+
try:
112+
obj = get_object_or_404(City, pk=pk)
113+
except Http404:
114+
return Response(data={
115+
'message': 'object with given id not found.',
116+
'success': False
117+
}, status=HTTPStatus.NOT_FOUND)
118+
return Response({
119+
'data': CitySerializer(instance=obj).data,
120+
'success': True
121+
}, status=HTTPStatus.OK)
122+
123+
def put(self, request, pk):
124+
try:
125+
obj = get_object_or_404(City, pk=pk)
126+
except Http404:
127+
return Response(data={
128+
'message': 'object with given id not found.',
129+
'success': False
130+
}, status=HTTPStatus.NOT_FOUND)
131+
serializer = CitySerializer(instance=obj, data=request.POST, partial=True)
132+
if not serializer.is_valid():
133+
return Response(data={
134+
**serializer.errors,
135+
'success': False
136+
}, status=HTTPStatus.BAD_REQUEST)
137+
serializer.save()
138+
return Response(data={
139+
'message': 'Record Updated.',
140+
'success': True
141+
}, status=HTTPStatus.OK)
142+
143+
def delete(self, request, pk):
144+
try:
145+
obj = get_object_or_404(City, pk=pk)
146+
except Http404:
147+
return Response(data={
148+
'message': 'object with given id not found.',
149+
'success': False
150+
}, status=HTTPStatus.NOT_FOUND)
151+
obj.delete()
152+
return Response(data={
153+
'message': 'Record Deleted.',
154+
'success': True
155+
}, status=HTTPStatus.OK)
156+

app1/__init__.py

Whitespace-only changes.

app1/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.

app1/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class App1Config(AppConfig):
5+
default_auto_field = "django.db.models.BigAutoField"
6+
name = "app1"

app1/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.db import models
2+
3+
# Create your models here.
4+
5+
class Book(models.Model):
6+
7+
title = models.CharField(max_length=100)
8+
info = models.CharField(max_length=100, default='')
9+
10+
class City(models.Model):
11+
12+
name = models.CharField(max_length=100)

app1/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.

app1/views.py

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

core/settings.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@
3737
"django.contrib.sessions",
3838
"django.contrib.messages",
3939
"django.contrib.staticfiles",
40+
41+
"app1",
42+
43+
'django_api_gen', # Django API GENERATOR # <-- NEW
44+
'rest_framework', # Include DRF # <-- NEW
45+
'rest_framework.authtoken', # Include DRF Auth # <-- NEW
46+
4047
]
4148

4249
MIDDLEWARE = [
@@ -121,3 +128,19 @@
121128
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
122129

123130
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
131+
132+
'''
133+
API_GENERATOR = {
134+
# pattern:
135+
# API_SLUG -> Import_PATH
136+
'books' : "app1.models.Book",
137+
'cities' : "app1.models.City",
138+
}
139+
'''
140+
141+
REST_FRAMEWORK = {
142+
'DEFAULT_AUTHENTICATION_CLASSES': [
143+
'rest_framework.authentication.SessionAuthentication',
144+
'rest_framework.authentication.TokenAuthentication',
145+
],
146+
}

core/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@
1414
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1515
"""
1616
from django.contrib import admin
17-
from django.urls import path
17+
from django.urls import path, include
18+
from rest_framework.authtoken.views import obtain_auth_token
1819

1920
urlpatterns = [
2021
path("admin/", admin.site.urls),
22+
path("api/", include("api.urls")),
23+
path('login/jwt/', view=obtain_auth_token),
2124
]

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
django
22
gunicorn
3+
django-api-generator

0 commit comments

Comments
 (0)