Skip to content

Commit

Permalink
Merge pull request #9 from iashraful/develop
Browse files Browse the repository at this point in the history
v2.1.1 Release from latest changes
  • Loading branch information
iashraful committed Mar 31, 2021
2 parents 9725845 + 1abc53e commit dab2529
Show file tree
Hide file tree
Showing 32 changed files with 204 additions and 155 deletions.
1 change: 0 additions & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test with python's default unittest
run: |
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 2.1.1
**ADDED**
* Added test cases for test app
* App directory structure has changed. But, no external effect.

**BUG FIXED**
* Import error and some other minor fixes

## 2.1.0
**ADDED**
* Added support for Django's prefetch and select related.
Expand Down
8 changes: 6 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
include LICENSE
include README.md
include CHANGELOG.md
recursive-include tests *.py
recursive-include docs

recursive-exclude example_app *
exclude urls.py
exclude wsgi.py
exclude settings.py
exclude manage.py
exclude manage.py
exclude docker*.yaml
exclude Dockerfile
exclude db.sqlite3
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
# Fast DRF [![Documentation Status](https://readthedocs.org/projects/fast-drf/badge/?version=latest)](https://fast-drf.readthedocs.io/en/latest/?badge=latest) [![Python packaging](https://github.com/iashraful/fast-drf/actions/workflows/python-package.yml/badge.svg?branch=master)](https://github.com/iashraful/fast-drf/actions/workflows/python-package.yml)


### Full Documentation [here](https://fast-drf.readthedocs.io/en/latest/)
### Change Log is [here](https://github.com/iashraful/fast-drf/blob/master/CHANGELOG.md)

> Fast DRF is a small library for making API faster with Django and Django REST Framework.
It's easy and configurable.

### Full Documentation [here](https://fast-drf.readthedocs.io/en/latest/)
### Change Log is [here](https://github.com/iashraful/fast-drf/blob/master/CHANGELOG.md)

### Quick Start
* Install the library inside your virtualenv by using pip `pip install fast-drf`
Expand Down
14 changes: 7 additions & 7 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ Fast DRF(Django REST Framework) is for making REST API development quicker/faste
## How it works?
It has a plain and simple architecture. It brings your configuration and create a runtime serializer and a runtime viewset. So, there is no option to slow down your API. It's similar as native rest framework.

**Procedure of execution**
* Locate the enabled apps from settings. If not read all the apps from installed apps.(I always recommend to keep **ENABLED_APPS** in settings)
* Read configurastion from each model.
* Create a runtime serializer and runtime view.
* Read REST framework configuration from settings.py and put them in viewset class. For example, You may have Custom Pagination class, Default Permission class like **IsAuthenticated** etc...
* Bind into urls. It's has a own router and the router return urlpatterns in a list.
**Procedure of execution**
* Locate the enabled apps from settings. If not read all the apps from installed apps.(I always recommend to keep **ENABLED_APPS** in settings)
* Read configuration from each model.
* Create a runtime serializer and runtime view.
* Read REST framework configuration from settings.py and put them in viewset class. For example, You may have Custom Pagination class, Default Permission class like **IsAuthenticated** etc...
* Bind into urls. It's has a own router and the router return urlpatterns in a list.

## Installation
* Install from pypy
Expand Down Expand Up @@ -147,4 +147,4 @@ class MyModel(ExposeApiModelMixin, models.Model):
# Only foreignkey fields
return ['field_1', 'field_2']
```
So, Where you have enabled the API and you have some relational fields you just need to declare them on the list to optimize the database joining.
So, Where you have enabled the API and you have some relational fields you just need to declare them on the list to optimize the database joining.
Empty file removed example_app/__init__.py
Empty file.
5 changes: 0 additions & 5 deletions example_app/apps.py

This file was deleted.

30 changes: 0 additions & 30 deletions example_app/migrations/0001_initial.py

This file was deleted.

33 changes: 0 additions & 33 deletions example_app/migrations/0002_post_testuser.py

This file was deleted.

19 changes: 0 additions & 19 deletions example_app/migrations/0003_post_author.py

This file was deleted.

26 changes: 0 additions & 26 deletions example_app/migrations/0004_auto_20190221_0730.py

This file was deleted.

Empty file removed example_app/migrations/__init__.py
Empty file.
Empty file removed example_app/tests/__init__.py
Empty file.
11 changes: 9 additions & 2 deletions fast_drf/core/serializer_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Any

from django.db import transaction
from django.db.models import OneToOneField, ForeignKey, Model
from django.db.models import ForeignKey, Model, OneToOneField
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.fields import empty
Expand Down Expand Up @@ -50,23 +51,29 @@ def update(self, instance: Model, validated_data: Any):
return instance

def create_relational_data(self, data, **kwargs):
# Getting the relational fields
relational_fields = _this.get_relational_fields()
# Iterate over the list
for field in relational_fields:
if field.name not in data.keys():
# If the field is not present on the given data(User inputted data)
continue
if type(data[field.name]) == dict:
_model = field.related_model
try:
# Creating related data here
related_instance = _model.objects.create(**data[field.name])
data.pop(field.name)
except TypeError:
raise ValidationError({'message': '{0} contains invalid data.'.format(field.name)})
raise ValidationError({'message': _('{0} contains invalid data.'.format(field.name))})
# While no error and data has created then assign the PK to the serializer field.
data[field.name] = related_instance.pk
return data

return RuntimeModelSerializer

def get_relational_fields(self, **kwargs):
# Currently we only have support for creating One2One and ForeignKey field support
_relational_fields = [OneToOneField, ForeignKey]
_fields = [f for f in self.model._meta.get_fields() if f.__class__ in _relational_fields]
return _fields
2 changes: 1 addition & 1 deletion fast_drf/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def get_urls(cls, **kwargs):
api_config=_model_api_config, details=True),
name=str(_model_api_config['api_url']) + '_details'
)]
except (ModuleNotFoundError,):
except (ModuleNotFoundError,) as error:
continue
return _urls

Expand Down
4 changes: 3 additions & 1 deletion fast_drf/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
__author__ = 'Ashraful'
__author__ = 'Ashraful'

default_app_config = 'fast_drf.tests.apps.FastDRFTestsConfig'
3 changes: 2 additions & 1 deletion fast_drf/tests/base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.test import TestCase
from example_app.models import Post
from .test_app.models import Post
from fast_drf.utils.enums import HTTPVerbsEnum


class FastDRFTestCase(TestCase):

def setUp(self):
self.model = Post
api_config = {
Expand Down
3 changes: 3 additions & 0 deletions fast_drf/tests/test_app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__author__ = 'Ashraful'

default_app_config = 'fast_drf.tests.test_app.apps.FastDRFTestsConfig'
6 changes: 6 additions & 0 deletions fast_drf/tests/test_app/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class FastDRFTestsConfig(AppConfig):
name = 'fast_drf.tests.test_app'
label = 'test_app'
59 changes: 59 additions & 0 deletions fast_drf/tests/test_app/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 3.1.7 on 2021-03-21 09:59

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import fast_drf.mixins.expose_api_model_mixin


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='PostMeta',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('meta_info', models.TextField(blank=True, null=True)),
],
),
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('phone', models.CharField(max_length=32)),
('address', models.TextField(verbose_name='Address')),
('dob', models.DateField(null=True)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
bases=(fast_drf.mixins.expose_api_model_mixin.ExposeApiModelMixin, models.Model),
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=256, null=True)),
('description', models.TextField(null=True)),
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='test_app.userprofile')),
('meta', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='posts', to='test_app.postmeta')),
],
bases=(fast_drf.mixins.expose_api_model_mixin.ExposeApiModelMixin, models.Model),
),
migrations.CreateModel(
name='TestUser',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('test_app.userprofile',),
),
]
1 change: 1 addition & 0 deletions fast_drf/tests/test_app/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = 'Ashraful'
8 changes: 4 additions & 4 deletions example_app/models.py → fast_drf/tests/test_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class UserProfile(ExposeApiModelMixin, models.Model):
dob = models.DateField(null=True)

class Meta:
app_label = 'example_app'
app_label = 'test_app'

@classmethod
def exposed_api(cls, *args, **kwargs):
Expand All @@ -26,7 +26,7 @@ def exposed_api(cls, *args, **kwargs):
class TestUser(UserProfile):
class Meta:
proxy = True
app_label = 'example_app'
app_label = 'test_app'

@classmethod
def exposed_api(cls, *args, **kwargs):
Expand All @@ -40,7 +40,7 @@ class PostMeta(models.Model):
meta_info = models.TextField(null=True, blank=True)

class Meta:
app_label = 'example_app'
app_label = 'test_app'


@classmethod
Expand All @@ -60,7 +60,7 @@ class Post(ExposeApiModelMixin, models.Model):
meta = models.ForeignKey(PostMeta, on_delete=models.SET_NULL, null=True, related_name='posts')

class Meta:
app_label = 'example_app'
app_label = 'test_app'

@classmethod
def exposed_api(cls, *args, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework.serializers import ModelSerializer

from example_app.models import Post
from fast_drf.tests.test_app.models import Post


class PostPrivateSerializer(ModelSerializer):
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion example_app/views.py → fast_drf/tests/test_app/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework.generics import ListCreateAPIView

from example_app.models import Post
from fast_drf.tests.test_app.models import Post


class PostAPIView(ListCreateAPIView):
Expand Down

0 comments on commit dab2529

Please sign in to comment.