## 1. Project Overview & Quickstart (Abdenasser/LICENSE)

# LICENSE

Open-source repository Abdenasser/LICENSE

### Repository Details
- **Repository:** [Abdenasser/LICENSE](https://github.com/Abdenasser/LICENSE)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (Abdenasser/Abdenasser.github.io)

## File: README.md

# gatsby-starter-point

This is a tweaked and restyled version of [Gatsby Starter](https://www.gatsbyjs.com/starters/teaware/gatsby-starter-point/) which I use for my personal blog @ [abdenasser.com](https://abdenasser.com) feel free to clone it and use it for your personal websites. :shipit:

## Basic Guide

Install dependencies

```
npm install
```

when it's done

```
gatsby develop
```

## Contact

Contact me on [twitter](https://twitter.com/__abdenasser).

---

## File: package.json

{
  "name": "gatsby-starter-point",
  "private": true,
  "description": "be water my friend",
  "version": "0.2.0",
  "author": "George Brown <teawares@gmail.com>",
  "bugs": {
    "url": "https://github.com/teaware/gatsby-starter-point/issues"
  },
  "dependencies": {
    "gatsby": "^2.24.47",
    "gatsby-image": "^2.4.16",
    "gatsby-plugin-dark-mode": "^1.1.2",
    "gatsby-plugin-manifest": "^2.4.23",
    "gatsby-plugin-offline": "^3.2.23",
    "gatsby-plugin-react-helmet": "^3.3.10",
    "gatsby-plugin-sass": "^2.3.12",
    "gatsby-plugin-sharp": "^2.6.27",
    "gatsby-plugin-transition-link": "^1.20.2",
    "gatsby-plugin-typography": "^2.5.10",
    "gatsby-remark-copy-linked-files": "^2.3.12",
    "gatsby-remark-images": "^3.3.25",
    "gatsby-remark-prismjs": "^3.5.10",
    "gatsby-remark-responsive-iframe": "^2.4.12",
    "gatsby-remark-smartypants": "^2.3.10",
    "gatsby-source-filesystem": "^2.3.24",
    "gatsby-transformer-remark": "^2.8.28",
    "gatsby-transformer-sharp": "^2.5.13",
    "gsap": "^3.5.0",
    "node-sass": "^4.14.1",
    "prismjs": "^1.21.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-headroom": "^3.0.0",
    "react-helmet": "^6.1.0",
    "react-typography": "^0.16.19",
    "typeface-merriweather": "0.0.72",
    "typeface-montserrat": "0.0.75",
    "typography": "^0.16.19",
    "typography-theme-wordpress-2016": "^0.16.19"
  },
  "devDependencies": {
    "prettier": "^2.0.5",
    "gh-pages": "^3.2.3"
  },
  "homepage": "https://gatsby-starter-point.netlify.app/",
  "license": "MIT",
  "scripts": {
    "build": "rm -rf public && rm -rf .cache && gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write '{gatsby-*.js,src/**/*.{js,jsx,json,css}}'",
    "start": "npm run develop",
    "serve": "gatsby serve",
    "deploy": "gatsby build && gh-pages -d public"
  }
}

---

## File: src/pages/my-personal-drf-serializers-draft/my-personal-drf-serializers-draft.md

---
title: "My personal drf serializer notes"
tags: ["django", "apis", "notes"]
date: "2021-09-03"
spoiler: "A use case driven draft, UDD 🤔 !!"
---



Before today it was only me and god who can read my hand writing, but today it is only god who can... today I got stuck reading one of my DRF drafts about `serializers` and decided that it's that time of the year again where I start thinking that I should have a blog where I can save my notes -then forget about it again-, but as I already got a blog I said why not 🤔 ? ... let's create a digital copy of my drf serializer notes, maybe someone will find it useful.

> save time creating django apis with [this cool django package](https://github.com/Abdenasser/dr_scaffold), and support the repository by dropping a star ⭐

<hr>

Let's define an Index or a table of content that we can use as reference in the future.

## Table of content

```
1 - Fields
  --------------------------
  - Serializer Method Field
  - Read Only Field
  - Custom Field Validation
  - Using Multiple Serializers
  --------------------------
2 - Data
  --------------------------
  - Custom Data Validation
  - Custom Output with `to_representation`()
  - Custom Input with `to_internal_value`().
  - Pass additional data directly to `save()`
  --------------------------
3 - Keywords
  --------------------------
  - The `source` Keyword
  - The `context` Keyword
```


<hr>

## 1- Fields

### Serializer Method Field

This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.

`SerializerMethodField` gets its data by calling `get_<field_name>`.

Example:

```python
class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = '__all__'

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days
```

### Read Only Field

Read-only fields are included in the API output, but should not be included in the input during create or update operations. Any `read_only` fields that are incorrectly included in the serializer input will be ignored.

Example:

```python
class AccountSerializer(serializers.Serializer):
    id = IntegerField(label='ID', read_only=True)
```

### Custom Field Validation

Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class.

With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class.

Let's take an example where we want to only allow students that have age between 12 and 18:

```python
class StudentSerializer(serializers.ModelSerializer):
    ...
    def validate_age(self, age):
        if age > 18 or age < 12:
            raise serializers.ValidationError('Age has to be between 12 and 18.')
        return age
```

### Using Multiple Serializers

You can override the `get_serializer_class()` of your `ViewSet` when for example you want to use a different Serializer in your create and update actions like the following:

```python
class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()

    def get_serializer_class(self):
        if self.action in ["create", "update"]:
            return WriteSerializer
        return ReadSerializer
```


<hr>

## 2- Data

### Custom Data Validation

Besides **Custom Field Validation**, there are two additional ways we can use to validate our data, when for example we need to compare some of our fields between each other the best way to do that is on the object level.

example:

```python
class OrderSerializer(serializers.ModelSerializer):
    ...
    def validate(self, data):
        if data['discount_amount'] > data['total_amount']:
            raise serializers.ValidationError('discount cannot be bigger than the total amount')
        return data
```

Another good way to do validation is when a validation logic is repeated multiple times in some serializers, you can then extract it to a function, example:

```python
def is_valid_age(value):
    if age < 12:
        raise serializers.ValidationError('age cannot be lower than 12.')
    elif age > 18:
        raise serializers.ValidationError('age cannot be higher than 18')
```

Then you can pass it like this in the other serializers:

```python
class AnotherSerializer(serializers.ModelSerializer):
    age = IntegerField(validators=[is_valid_age])
```

### Custom Output with `to_representation()`

When you want to customize the output right before it is sent use `to_representation()`, imagine you have an output like the following after serialization is completed:

```json
{
  "id": 1,
  "username": "abdenasser",
  "bio": "Hey ... you already know!",
  "followed_by": [2, 3]
}
```

and you want to add a total followers count to it... you can simply do:

```python
class ResourceSerializer(serializers.ModelSerializer):
    ...
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['followers'] = instance.followed_by.count()
        return representation
```

Then you'll get:

```json
{
  "id": 1,
  "username": "abdenasser",
  "bio": "Hey ... you already know!",
  "followed_by": [2, 3],
  "followers": 2
}
```

### Custom Input with `to_internal_value()`

Let's say that your API is expecting some input from a 3rd party service and you are only interested in a chunk of that input, you can use `to_internal_value()` as follow:

```python
class SomeSerializer(serializers.ModelSerializer):
    ...
    def to_internal_value(self, data):
        useful_data = data['useful']
        return super().to_internal_value(useful_data)
```

### Pass additional data directly to save()

Calling `.save()` will either create a new instance, or update an existing instance, depending on if an existing instance was passed when instantiating the serializer class:

```python
# .save() will create a new instance.
serializer = CommentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
```


<hr>

## 3- Keywords

### The source Keyword

In essence, you can use `source` in a field like this

```python
field_name = serializers.SomeFieldType(source='prop')
```

where `prop` could be a call for a function that return some value, or a property that exists in a related model like `...(source='author.bio')` or even a serializer field that you want to rename in output.

You can also attach the whole object with `source='*'` if you need.

### The context Keyword

You can provide arbitrary additional context by passing a context argument when instantiating a serializer. For example:

```python
resource = Resource.objects.get(id=1)
serializer = ResourceSerializer(resource, context={'key': 'value'})
```

The context dictionary can then be used within any serializer field logic, such as a custom .to_representation() method, by accessing the self.context attribute.

```python
def to_representation(self, instance):
    representation = super().to_representation(instance)
    representation['key'] = self.context['key']

    return representation
```



## Final word:

Django Rest Framework has a very good documentation which you can find and read [here](https://www.django-rest-framework.org/), try to spend some time on it and use it as a fall back any time you feel that things started getting complicated in your serializers, also bare in mind that while you are using serializers you are most of the time using, overriding or extending the base serializer functionalities so go check it out and take a look at it [here](https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py).

---

## File: src/pages/scaffold-django-apis/scaffold-django-apis.md

---
title: "Scaffold django apis like a champion"
tags: ["django", "python", "oss"]
date: "2021-08-26"
spoiler: "The very first blog post"
---



Hey 👋 my name is Abdenasser I'll give you a proper introduction to who I'm in the next blog, but today I'll show you how to use this little django scaffold library I crafted last week https://github.com/Abdenasser/dr_scaffold to create a ready to use and fully functional REST apis with django only using the command line, let's get started.

Setting a django environment is outside of the scope of this article, I'm sure there's a lot of guides and tutorials on how to do that all over internet you can follow one of them and get back, I'll be waiting for you just right here!

In a nutshell here is what we gonna do in three steps:

1. Create a django project
2. Setup django rest framework and dr_scaffold
3. Scaffold a blog api with Articles and Authors

# 1. Create a django project:

Let's create a django project using this django-admin command:

```bash
$ django-admin startproject myApi
```

this command does the same as `python manage.py startproject myApi` the only difference is that it doesn't require a python environment to get executed.

Let's then cd to our newly created django project `cd myApi` and create a virtualenv with:

```bash
$ python3 -m virtualenv env
```

Finally let's activate our virtual env with:

```bash
$ source env/bin/activate
```

# 2. Setup django rest framework and dr_scaffold:

Let's install django rest framework and dr_scaffold packages using pip like the following:

```bash
$ pip install djangorestframework
$ pip install dr-scaffold
```

Next let's add these packages to our project `INSTALLED_APPS` inside `myApi/settings.py` like this:

```python
INSTALLED_APPS = [
    ...,
    'rest_framework',
    'dr_scaffold'
]
```

Then let's add our core and api folders settings to `myApi/settings.py`, (for the simplicity of the tutorial we'll leave them empty):

```python
CORE_FOLDER = ""  # you can leave them empty
API_FOLDER = ""   # or set them to be the same
```

# 3. Scaffold a blog api with Articles and Authors

Our blog api will be composed of two main resources an Article and a Author, Let's scaffold our Author first:

```bash
$ python manage.py dr_scaffold blog Author name:charfield
🎉 Your RESTful Author api resource is ready 🎉
```

this command will generate a blog folder with `models.py` > `admin.py` `views.py` `serializers.py` `urls.py` all populated with appropriate code that your REST api needs for Author resource

Lets also generate the Article resource:

```bash
$ python manage.py dr_scaffold blog Post body:textfield author:foreignkey:Author
🎉 Your RESTful Post api resource is ready 🎉
```

this command will do the same thing but also will add a relation to our Author resource through a `foreignkey` field.

In order to generate the database tables let's add blog to our `INSTALLED_APPS` inside `myApi/settings.py`:

```python
INSTALLED_APPS = [
    ...,
    'rest_framework',
    'dr_scaffold',
    'blog'
]
```

Then let's run these commands to generate our migrations and migrate the database:

```bash
$ python manage.py makemigrations
$ python manage.py migrate
```

Finally add our blog to our project's `urlpatterns` inside `myApi/urls.py`:

```python
urlpatterns = [
    ...,
    path("blog/", include("blog.urls")),
]
```

Don't forget to import include in your project's `urls.py` like so :

```python
from django.conf.urls import include
```

Your `urls.py` should look something like this in the end:

```python
from django.conf.urls import include #our added import
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    path("blog/", include("blog.urls")), #our added bol path
]
```

Now that we are completely done let's run `python manage.py runserver` and head over to `http://127.0.0.1:8000/blog/` to see your fully created REST blog API.. and also you can generate a super user with `python manage.py createsuperuser` then head over to `http://127.0.0.1:8000/admin` to check the admin panel.

Don't forget to star the [repo](https://github.com/Abdenasser/dr_scaffold) on github If you like it.. Enjoy 🎉 !