steps Flashcards

1
Q

To create a new project named “djangoappname”

A

django-admin startproject djangoappname .

Don’t forget to add the . dot at the end of this command. This will actually generate all the files in the current directory

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Before starting the server, let’s run the migrations. after creating the CoreRoot project, execute

A

python manage.py migrate

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

start the Django server:

A

python manage.py runserver

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

set up a postgres database:

A

> sudo su postgres

> psql

> CREATE DATABASE coredb;

> CREATE USER coreuser WITH PASSWORD ‘wCh29&HE&T83’;

> GRANT ALL PRIVILEGES ON DATABASE coredb TO coreuser;

> ALTER USER core CREATEDB;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

how to configure the project to connect to a database.

A

In the settings.py file:

https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’,
‘NAME’: ‘coredb’,
‘USER’: ‘coreuser’,
‘PASSWORD’: ‘wCh29&HE&T83’,
‘HOST’: ‘localhost’,
‘PORT’: ‘5342’,
}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

run the migrations

A

python manage.py migrate

to see django logo/running
go to
https://www.educative.io/courses/full-stack-django-and-react/configuring-the-database

second black screen (after db conf and connection)

execute first steps (migration/runserver)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

When working with Django, To have a clean and well-organized project,

A

we’ll have to create many apps to handle different parts of a project.

For example, we can have a different application for authentication, and another for payments or articles.

  • django-api
    • core
      • apps.py
    • CoreRoot
      • settings.py

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

At the root of the project, inside “djangoappname” folder, run the following command to Create the core application

A
  • RUN django-admin startapp core
  • remove all the files in this app except for the apps.py file and the __init__.py file.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Inside apps.py, add the last line (“label” class property) of the following code:

A

from django.apps import AppConfig

class CoreConfig(AppConfig):
default_auto_field = ‘django.db.models.BigAutoField’
name = ‘core’
label = ‘core’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Register the app in the INSTALLED_APPS list inside the settings.py file of the project:

A

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,

'core' ]
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

creating a User application (submodule)

A

inside”djangoappname” folder

#inside”core”AppFolder
django-admin startapp user

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

User table structure

public_id: string
last_name: string
first_name: string
username: string
bio: string
avatar: image
email: string
is_active
is_superuser
created: datetime
updated: datetime

in Django ORM:

A

import uuid

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.http import Http404

class User(AbstractBaseUser, PermissionsMixin):
public_id = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4, editable=False)
username = models.CharField(db_index=True, max_length=255, unique=True)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)

email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)

created = models.DateTimeField(auto_now=True)
updated = models.DateTimeField(auto_now_add=True)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

objects = UserManager()

def \_\_str\_\_(self):
    return f"{self.email}"

@property
def name(self):
    return f"{self.first_name} {self.last_name}"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

The models module from Django provides

A
  • field utilities
  • model property
  • __str__ method to return a string that can help us quickly identify a User object.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Let’s write UserManager so we can have methods to create a user and a superuser:

A

class UserManager(BaseUserManager):
def get_object_by_public_id(self, public_id):

    try:
        instance = self.get(public_id=public_id)
        return instance
    except (ObjectDoesNotExist, ValueError, TypeError):
        return Http404

def create_user(self, username, email, password=None, **kwargs):
    """Create and return a `User` with an email, phone number, username and password."""
    if username is None:
        raise TypeError('Users must have a username.')
    if email is None:
        raise TypeError('Users must have an email.')
    if password is None:
        raise TypeError('User must have an email.')

    user = self.model(username=username, email=self.normalize_email(email), **kwargs)
    user.set_password(password)
    user.save(using=self._db)

    return user

def create_superuser(self, username, email, password, **kwargs):
    """
    Create and return a `User` with superuser (admin) permissions.
    """
    if password is None:
        raise TypeError('Superusers must have a password.')
    if email is None:
        raise TypeError('Superusers must have an email.')
    if username is None:
        raise TypeError('Superusers must have an username.')

    user = self.create_user(username, email, password, **kwargs)
    user.is_superuser = True
    user.is_staff = True
    user.save(using=self._db)

    return user
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Before running the migrations (everytime a new app was added to the project)

A

we need to register the user application in INSTALLED_APPS in CoreRoot/settings.py.

goto /projectFolder/CoreRoot/settings.py
> add the new app: core.newapp

inside the new app folder in Apps.py:
###
from django.apps import AppConfig
class UserConfig(AppConfig):
default_auto_field = ‘django.db.models.BigAutoField’
name = ‘core.user’
label = ‘core_user’
###
Where name and name show how apps are nested

tell Django to use this User model for the authentication user model. In the settings.py file, add the following line:
goto /projectFolder/CoreRoot/settings.py
> at the end of the file add: AUTH_USER_MODEL = ‘core_user.User’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

after add a new model to the project, create the first migration for the new app (the app that contains the Models.py file,

A

python manage.py makemigrations

17
Q

Testing the model

A

use the Django shell to play with the newly created model a little bit

18
Q

Testing the model with Shell

A

the data needed to create a user

python manage.py shell

from core.user.models import User
data_user = {
“email”: “testuser@yopmail.com”,
“username”: “john-doe”,
“password”: “12345”,
“first_name”: “John”,
“last_name”: “Doe”
}
user = User.objects.create_user(**data_user)

user.name
user.email
user.password

19
Q

install the djangorestframework package

A

add rest_framework to the INSTALLED_APPS setting:

INSTALLED_APPS = [

‘rest_framework’,

]

20
Q

Writing UserSerializer (interface between viewset and model)

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/writing-userserializer-and-userviewset:

In the core/user directory,

create a file called serializers.py:
from rest_framework import serializers
from core.user.models import User

class UserSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source=’public_id’, read_only=True, format=’hex’)
created = serializers.DateTimeField(read_only=True)
updated = serializers.DateTimeField(read_only=True)

class Meta:
    model = User
    fields = ['id', 'username', 'first_name', 'last_name', 'bio', 'avatar', 'email', 'is_active', 'created', 'updated']
    read_only_field = ['is_active']
21
Q

write the viewset.

A

Inside the user directory,
rename the view file viewsets.py

from rest_framework.permissions import AllowAny
from rest_framework import viewsets
from core.user.serializers import UserSerializer
from core.user.models import User

class UserViewSet(viewsets.ModelViewSet):
http_method_names = (‘patch’, ‘get’)
permission_classes = (IsAuthenticated,) #AllowAny
serializer_class = UserSerializer

// used by the viewset to get a list of all the users.
// called when /user/ is hit with a GET request
def get_queryset(self):
    if self.request.user.is_superuser:
        return User.objects.all()
    return User.objects.exclude(is_superuser=True)

// called when a GET or PUT request is made on the /user/id/
def get_object(self):
    obj = User.objects.get_object_by_public_id(self.kwargs['pk'])
    self.check_object_permissions(self.request, obj)
    return obj
22
Q

a viewset to which we will be adding a router

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/adding-a-router:

At the root of the apps project (core),

create a file named routers.py

from rest_framework import routers
from core.user.viewsets import UserViewSet

router = routers.SimpleRouter()

router.register(r’user’, UserViewSet, basename=’user’)

urlpatterns = [
*router.urls,
]

23
Q

make sure that we have the server running:

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/adding-a-router:

python manage.py runserwever

(Click the “Run” button to start Insomnia.)

24
Q

Doing requests with Insomnia

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/adding-a-router:

make a GET request to http://0.0.0.0:8000/api/user/

make a GET request to retrieve the first user using this URL: /api/user/<id>/</id>

make a PATCH request to update a field in the first user using this URL: /api/user/<id>/
> add a JSON body, setting the last_name value for this user to "Cat"
{"last_name":"Cat}</id>

25
Q

test authentication issue

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/adding-a-router:

permission_classes = (IsAuthenticated,) #AllowAny

26
Q

installed the djangorestframework-simplejwt authentication plugin

A

for DRF to handle JWT authentication

it facilitates the creation and management of access tokens, as well as refreshing tokens.

A) We need to register the app in INSTALLED_APPS: ‘rest_framework_simplejwt’

B) specify DEFAULT_AUTHENTICATION_CLASSES in the REST_FRAMEWORK dictionary:

REST_FRAMEWORK = {
‘DEFAULT_AUTHENTICATION_CLASSES’: (
‘rest_framework_simplejwt.authentication.JWTAuthentication’,
),

27
Q

create a new application called auth in the core application:

A

cd core

django-admin startapp auth

It’ll contain all the logic concerning logging in, registration, logging out, and a lot more.

28
Q

rewrite the apps.py file and register the application’s name in the INSTALLED_APPS settings:

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/writing-the-user-registration-feature:

from django.apps import AppConfig
class AuthConfig(AppConfig):
default_auto_field = ‘django.db.models.BigAutoField’
name = ‘core.auth’
label = ‘core_auth’

INSTALLED_APPS:

‘core’,
‘core.user’,
‘core.auth’
]

29
Q

For registration and login, we’ll have many serializers and viewsets

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/writing-the-user-registration-feature:

remove the admin.py and models.py files from the auth directory

Create a Python package called serializers and another one called viewsets
*** Make sure each directory have an __init__.py file.

auth app tree should look like:
- apps.py
- __init__.py
- migrations
- __init__.py
- serializers
- __init__.py
- tests.py
- viewsets
- __init__.py
- views.py

> Inside the serializers directory, create a file called register.py:

from rest_framework import serializers
from core.user.serializers import UserSerializer
from core.user.models import User

class RegisterSerializer(UserSerializer):
password = serializers.CharField(max_length=128, min_length=8, write_only=True, required=True)

class Meta:
model = User
fields = [‘id’, ‘bio’, ‘avatar’, ‘email’, ‘username’, ‘first_name’, ‘last_name’, ‘password’]

def create(self, validated_data):
    # Use the `create_user` method we wrote earlier for the UserManager to create a new user.
    return User.objects.create_user(**validated_data)

> > Inside the viewsets directory, create a file called register.py:
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import AllowAny
from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken
from core.auth.serializers import RegisterSerializer

class RegisterViewSet(ViewSet):
serializer_class = RegisterSerializer
permission_classes = (AllowAny,)
http_method_names = [‘post’]
# rewriting the create method to add access and refresh tokens in the body of the response.
def create(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
refresh = RefreshToken.for_user(user)
res = {
“refresh”: str(refresh),
“access”: str(refresh.access_token),
}
return Response({
“user”: serializer.data,
“refresh”: res[“refresh”],
“token”: res[“access”]
}, status=status.HTTP_201_CREATED)

> register the viewset in the routers.py file:
from core.auth.viewsets import RegisterViewSet
router.register(r’auth/register’, RegisterViewSet, basename=’auth-register’)

30
Q

Click the “Run” button to launch Insomnia and send requests.

A

Playground at https://www.educative.io/courses/full-stack-django-and-react/writing-the-user-registration-feature:

The URL will be as follows: http://0.0.0.0:8000/api/auth/register/

As a body for the request, we can pass the following:
{
“username”: “mouse21”,
“first_name”: “Mickey”,
“last_name”: “Mouse”,
“password”: “12345678”,
“email”: “mouse@yopmail.com”
}

31
Q

Inside the core/auth/serializers directory, create a new file called login.py

A

playground at https://www.educative.io/courses/full-stack-django-and-react/adding-the-login-feature:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.settings import api_settings
from django.contrib.auth.models import update_last_login
from core.user.serializers import UserSerializer

class LoginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data[‘user’] = UserSerializer(self.user).data
data[‘refresh’] = str(refresh)
data[‘access’] = str(refresh.access_token)
if api_settings.UPDATE_LAST_LOGIN:
update_last_login(None, self.user)
return data

32
Q

import LoginSerializer (login.py) to the (auth/serializers/)_init__.py file:

A

playground at https://www.educative.io/courses/full-stack-django-and-react/adding-the-login-feature:

from .login import LoginSerializer

33
Q

Adding the (auth/viewsets) LoginViewset (login.py)

A

playground at https://www.educative.io/courses/full-stack-django-and-react/adding-the-login-feature:

from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import AllowAny
from rest_framework import status
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
from core.auth.serializers import LoginSerializer

class LoginViewSet(ViewSet):
serializer_class = LoginSerializer
permission_classes = (AllowAny,)
http_method_names = [‘post’]

def create(self, request, *args, **kwargs):
    serializer = self.serializer_class(data=request.data)
    try:
        serializer.is_valid(raise_exception=True)
    except TokenError as e:
        raise InvalidToken(e.args[0])
    return Response(serializer.validated_data, status=status.HTTP_200_OK)
34
Q

Add the viewset to the __init__.py file of the auth/viewsets directory:

A

playground at https://www.educative.io/courses/full-stack-django-and-react/adding-the-login-feature:

from .login import LoginViewSet

35
Q

import LoginViewSet and register it in the routers.py

A

from core.auth.viewsets import LoginViewSet
router.register(r’auth/login’, LoginViewSet, basename=’auth-login’)

36
Q

try a request with Insomnia at /auth/login

A

playground at https://www.educative.io/courses/full-stack-django-and-react/adding-the-login-feature:

Here’s the body of the request we’ll use:

{
“password”: “12345678”,
“email”: “mouse2@yopmail.com”
}

37
Q

refresh logic feature

A

playground at https://www.educative.io/courses/full-stack-django-and-react/refresh-logic:

a) In auth/viewsets, add a new file called refresh.py:
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenRefreshView
from rest_framework.permissions import AllowAny
from rest_framework import status
from rest_framework import viewsets
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken

class RefreshViewSet(viewsets.ViewSet, TokenRefreshView):
permission_classes = (AllowAny,)
http_method_names = [‘post’]
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except TokenError as e:
raise InvalidToken(e.args[0])
return Response(serializer.validated_data, status=status.HTTP_200_OK)

b) add the class in the __init__.py file:
from .refresh import RefreshViewSet

c) register it in the routers.py file:
from core.auth.viewsets import RefreshViewSet
router.register(r’auth/refresh’, RefreshViewSet, basename=’auth-refresh’)

d)
Send a login POST request to the /auth/login endpoint with the following credentials:
{
“password”: “12345678”,
“email”:”mouse2@yopmail.com”
}

e) test the new endpoint at /auth/refresh/ to get a new token:
POST the request with the “refresh” token in the body of the request