├── .gitignore ├── Starter Code ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── db.sqlite3 ├── drf_course │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── __init__.cpython-39.pyc │ │ ├── settings.cpython-310.pyc │ │ ├── settings.cpython-39.pyc │ │ ├── urls.cpython-310.pyc │ │ ├── urls.cpython-39.pyc │ │ ├── wsgi.cpython-310.pyc │ │ └── wsgi.cpython-39.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video1 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── models.dot └── requirements.txt ├── Video11 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video12 & 13 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video14 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video15 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video16 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video17 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video18 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video19 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video2 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video20 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video21 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video22 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video23 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video24 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video25 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video26 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── signals.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video27 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── signals.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video28 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── signals.py │ ├── tests.py │ ├── throttles.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video29 ├── api.http ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── filters.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── paginate.py │ ├── serializers.py │ ├── signals.py │ ├── tests.py │ ├── throttles.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt └── schema.yml ├── Video3 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video4 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video5 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video6 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video7 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── Video8 ├── api │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── management │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── populate_db.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── serializers.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── drf_course │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements.txt └── Video9 & 10 ├── api ├── __init__.py ├── admin.py ├── apps.py ├── management │ └── commands │ │ ├── __init__.py │ │ └── populate_db.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── serializers.py ├── tests.py ├── urls.py └── views.py ├── drf_course ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | db.sqlite3 4 | .env -------------------------------------------------------------------------------- /Starter Code/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/api/__init__.py -------------------------------------------------------------------------------- /Starter Code/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Starter Code/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Starter Code/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Starter Code/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/api/migrations/__init__.py -------------------------------------------------------------------------------- /Starter Code/api/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import AbstractUser 3 | -------------------------------------------------------------------------------- /Starter Code/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Starter Code/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | 6 | ] 7 | -------------------------------------------------------------------------------- /Starter Code/api/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | -------------------------------------------------------------------------------- /Starter Code/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/db.sqlite3 -------------------------------------------------------------------------------- /Starter Code/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__init__.py -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/settings.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/settings.cpython-310.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/settings.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/settings.cpython-39.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/urls.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/urls.cpython-310.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/urls.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/urls.cpython-39.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/wsgi.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/wsgi.cpython-310.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/__pycache__/wsgi.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/drf_course/__pycache__/wsgi.cpython-39.pyc -------------------------------------------------------------------------------- /Starter Code/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Starter Code/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')) 7 | ] 8 | -------------------------------------------------------------------------------- /Starter Code/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Starter Code/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Starter Code/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Starter Code/requirements.txt -------------------------------------------------------------------------------- /Video1/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/api/__init__.py -------------------------------------------------------------------------------- /Video1/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video1/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video1/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video1/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video1/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video1/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | 6 | ] 7 | -------------------------------------------------------------------------------- /Video1/api/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | -------------------------------------------------------------------------------- /Video1/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/drf_course/__init__.py -------------------------------------------------------------------------------- /Video1/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video1/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')) 7 | ] 8 | -------------------------------------------------------------------------------- /Video1/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video1/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video1/models.dot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/models.dot -------------------------------------------------------------------------------- /Video1/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video1/requirements.txt -------------------------------------------------------------------------------- /Video11/api.http: -------------------------------------------------------------------------------- 1 | GET http://localhost:8000/products/ HTTP/1.1 2 | 3 | ### 4 | 5 | POST http://localhost:8000/products/ HTTP/1.1 6 | Content-Type: application/json 7 | 8 | { 9 | "name": "Television", 10 | "price": 300.00, 11 | "stock": 14, 12 | "description": "An amazing new TV" 13 | } -------------------------------------------------------------------------------- /Video11/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video11/api/__init__.py -------------------------------------------------------------------------------- /Video11/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) -------------------------------------------------------------------------------- /Video11/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video11/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video11/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video11/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video11/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video11/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 28 | -------------------------------------------------------------------------------- /Video11/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video11/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video11/drf_course/__init__.py -------------------------------------------------------------------------------- /Video11/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video11/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video11/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video11/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video11/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video11/requirements.txt -------------------------------------------------------------------------------- /Video12 & 13/api.http: -------------------------------------------------------------------------------- 1 | GET http://localhost:8000/products/ HTTP/1.1 2 | 3 | ### 4 | 5 | POST http://localhost:8000/products/ HTTP/1.1 6 | Content-Type: application/json 7 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzI4MzIxOTM0LCJpYXQiOjE3MjgzMjE2MzQsImp0aSI6ImJhNjAwMDBiMTU3MzRkM2ZhMWZlN2VlNWY4ZDQ5NzE5IiwidXNlcl9pZCI6MX0.oytJ-fpp0gf4STT7qoGNBFHrGVHyexLYW2ZqGPL1gxU 8 | 9 | { 10 | "name": "Television", 11 | "price": 300.00, 12 | "stock": 14, 13 | "description": "An amazing new TV" 14 | } 15 | 16 | ### 17 | POST http://localhost:8000/api/token/ HTTP/1.1 18 | Content-Type: application/json 19 | 20 | { 21 | "username": "admin", 22 | "password": "test" 23 | } 24 | 25 | ### 26 | POST http://localhost:8000/api/token/refresh/ HTTP/1.1 27 | Content-Type: application/json 28 | 29 | { 30 | "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTcyODQwOTAzMSwiaWF0IjoxNzI4MzIyNjMxLCJqdGkiOiI3ZjdmZDExNDhjZTg0Njk5YTdiYmY2OWZlNmRiMzczYSIsInVzZXJfaWQiOjF9.KRzvCrbOC_XbxFqjGWf9iTf4lhlnWAdddfCjp7dPrFM" 31 | } 32 | -------------------------------------------------------------------------------- /Video12 & 13/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video12 & 13/api/__init__.py -------------------------------------------------------------------------------- /Video12 & 13/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) -------------------------------------------------------------------------------- /Video12 & 13/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video12 & 13/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video12 & 13/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video12 & 13/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video12 & 13/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video12 & 13/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video12 & 13/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video12 & 13/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video12 & 13/drf_course/__init__.py -------------------------------------------------------------------------------- /Video12 & 13/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video12 & 13/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | 8 | urlpatterns = [ 9 | path('admin/', admin.site.urls), 10 | path('', include('api.urls')), 11 | path('silk/', include('silk.urls', namespace='silk')), 12 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 13 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 14 | ] 15 | -------------------------------------------------------------------------------- /Video12 & 13/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video12 & 13/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video12 & 13/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video12 & 13/requirements.txt -------------------------------------------------------------------------------- /Video14/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video14/api/__init__.py -------------------------------------------------------------------------------- /Video14/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) -------------------------------------------------------------------------------- /Video14/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video14/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video14/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video14/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video14/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video14/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video14/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video14/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video14/drf_course/__init__.py -------------------------------------------------------------------------------- /Video14/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video14/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | 8 | urlpatterns = [ 9 | path('admin/', admin.site.urls), 10 | path('', include('api.urls')), 11 | path('silk/', include('silk.urls', namespace='silk')), 12 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 13 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 14 | ] 15 | -------------------------------------------------------------------------------- /Video14/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video14/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video14/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video14/requirements.txt -------------------------------------------------------------------------------- /Video15/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video15/api/__init__.py -------------------------------------------------------------------------------- /Video15/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) -------------------------------------------------------------------------------- /Video15/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video15/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video15/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video15/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video15/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video15/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video15/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video15/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video15/drf_course/__init__.py -------------------------------------------------------------------------------- /Video15/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video15/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video15/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video15/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video15/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video15/requirements.txt -------------------------------------------------------------------------------- /Video16/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video16/api/__init__.py -------------------------------------------------------------------------------- /Video16/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) -------------------------------------------------------------------------------- /Video16/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video16/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product 3 | 4 | 5 | class ProductFilter(django_filters.FilterSet): 6 | class Meta: 7 | model = Product 8 | fields = { 9 | 'name': ['iexact', 'icontains'], 10 | 'price': ['exact', 'lt', 'gt', 'range'] 11 | } -------------------------------------------------------------------------------- /Video16/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video16/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video16/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video16/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video16/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video16/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video16/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video16/drf_course/__init__.py -------------------------------------------------------------------------------- /Video16/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video16/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video16/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video16/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video16/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video16/requirements.txt -------------------------------------------------------------------------------- /Video17/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video17/api/__init__.py -------------------------------------------------------------------------------- /Video17/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video17/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video17/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product 3 | 4 | 5 | class ProductFilter(django_filters.FilterSet): 6 | class Meta: 7 | model = Product 8 | fields = { 9 | 'name': ['iexact', 'icontains'], 10 | 'price': ['exact', 'lt', 'gt', 'range'] 11 | } -------------------------------------------------------------------------------- /Video17/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video17/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video17/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video17/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video17/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video17/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video17/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video17/drf_course/__init__.py -------------------------------------------------------------------------------- /Video17/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video17/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video17/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video17/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video17/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video17/requirements.txt -------------------------------------------------------------------------------- /Video18/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video18/api/__init__.py -------------------------------------------------------------------------------- /Video18/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video18/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video18/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } -------------------------------------------------------------------------------- /Video18/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video18/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video18/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video18/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video18/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video18/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video18/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video18/drf_course/__init__.py -------------------------------------------------------------------------------- /Video18/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video18/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video18/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video18/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video18/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video18/requirements.txt -------------------------------------------------------------------------------- /Video19/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video19/api/__init__.py -------------------------------------------------------------------------------- /Video19/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video19/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video19/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } -------------------------------------------------------------------------------- /Video19/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video19/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video19/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video19/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video19/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video19/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video19/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video19/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video19/drf_course/__init__.py -------------------------------------------------------------------------------- /Video19/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video19/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video19/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video19/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video19/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video19/requirements.txt -------------------------------------------------------------------------------- /Video2/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video2/api/__init__.py -------------------------------------------------------------------------------- /Video2/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video2/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video2/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video2/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video2/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video2/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video2/api/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from .models import Product, Order, OrderItem 3 | 4 | 5 | class ProductSerializer(serializers.ModelSerializer): 6 | class Meta: 7 | model = Product 8 | fields = ( 9 | 'id', 10 | 'name', 11 | 'price', 12 | 'stock', 13 | ) 14 | 15 | def validate_price(self, value): 16 | if value <= 0: 17 | raise serializers.ValidationError( 18 | "Price must be greater than 0." 19 | ) 20 | return value -------------------------------------------------------------------------------- /Video2/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video2/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.product_list), 6 | path('products//', views.product_detail), 7 | ] 8 | -------------------------------------------------------------------------------- /Video2/api/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import get_object_or_404 2 | from api.serializers import ProductSerializer 3 | from api.models import Product 4 | from rest_framework.response import Response 5 | from rest_framework.decorators import api_view 6 | 7 | 8 | @api_view(['GET']) 9 | def product_list(request): 10 | products = Product.objects.all() 11 | serializer = ProductSerializer(products, many=True) 12 | return Response(serializer.data) 13 | 14 | @api_view(['GET']) 15 | def product_detail(request, pk): 16 | product = get_object_or_404(Product, pk=pk) 17 | serializer = ProductSerializer(product) 18 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video2/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video2/drf_course/__init__.py -------------------------------------------------------------------------------- /Video2/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video2/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')) 7 | ] 8 | -------------------------------------------------------------------------------- /Video2/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video2/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video2/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video2/requirements.txt -------------------------------------------------------------------------------- /Video20/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video20/api/__init__.py -------------------------------------------------------------------------------- /Video20/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video20/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video20/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | -------------------------------------------------------------------------------- /Video20/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video20/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video20/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video20/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video20/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video20/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video20/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | ] 10 | 11 | router = DefaultRouter() 12 | router.register('orders', views.OrderViewSet) 13 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video20/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video20/drf_course/__init__.py -------------------------------------------------------------------------------- /Video20/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video20/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video20/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video20/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video20/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video20/requirements.txt -------------------------------------------------------------------------------- /Video21/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video21/api/__init__.py -------------------------------------------------------------------------------- /Video21/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video21/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video21/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video21/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video21/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video21/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video21/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video21/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video21/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video21/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | ] 10 | 11 | router = DefaultRouter() 12 | router.register('orders', views.OrderViewSet) 13 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video21/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video21/drf_course/__init__.py -------------------------------------------------------------------------------- /Video21/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video21/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video21/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video21/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video21/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video21/requirements.txt -------------------------------------------------------------------------------- /Video22/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video22/api/__init__.py -------------------------------------------------------------------------------- /Video22/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video22/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video22/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video22/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video22/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video22/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video22/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video22/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video22/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video22/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | ] 10 | 11 | router = DefaultRouter() 12 | router.register('orders', views.OrderViewSet) 13 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video22/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video22/drf_course/__init__.py -------------------------------------------------------------------------------- /Video22/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video22/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video22/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video22/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video22/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video22/requirements.txt -------------------------------------------------------------------------------- /Video23/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video23/api/__init__.py -------------------------------------------------------------------------------- /Video23/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video23/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video23/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video23/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video23/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video23/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video23/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video23/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video23/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video23/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | ] 10 | 11 | router = DefaultRouter() 12 | router.register('orders', views.OrderViewSet) 13 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video23/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video23/drf_course/__init__.py -------------------------------------------------------------------------------- /Video23/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video23/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video23/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video23/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video23/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video23/requirements.txt -------------------------------------------------------------------------------- /Video24/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video24/api/__init__.py -------------------------------------------------------------------------------- /Video24/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video24/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video24/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video24/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video24/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video24/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video24/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video24/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video24/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video24/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | ] 10 | 11 | router = DefaultRouter() 12 | router.register('orders', views.OrderViewSet) 13 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video24/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video24/drf_course/__init__.py -------------------------------------------------------------------------------- /Video24/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video24/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video24/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video24/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video24/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video24/requirements.txt -------------------------------------------------------------------------------- /Video25/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video25/api/__init__.py -------------------------------------------------------------------------------- /Video25/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video25/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video25/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video25/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video25/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video25/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video25/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video25/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video25/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video25/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | path('users/', views.UserListView.as_view()), 10 | ] 11 | 12 | router = DefaultRouter() 13 | router.register('orders', views.OrderViewSet) 14 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video25/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video25/drf_course/__init__.py -------------------------------------------------------------------------------- /Video25/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video25/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video25/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video25/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video25/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video25/requirements.txt -------------------------------------------------------------------------------- /Video26/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video26/api/__init__.py -------------------------------------------------------------------------------- /Video26/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video26/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | 8 | def ready(self): 9 | from . import signals 10 | -------------------------------------------------------------------------------- /Video26/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video26/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video26/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video26/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video26/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video26/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video26/api/signals.py: -------------------------------------------------------------------------------- 1 | from django.db.models.signals import post_save, post_delete 2 | from django.dispatch import receiver 3 | from api.models import Product 4 | from django.core.cache import cache 5 | 6 | 7 | @receiver([post_save, post_delete], sender=Product) 8 | def invalidate_product_cache(sender, instance, **kwargs): 9 | """ 10 | Invalidate product list caches when a product is created, updated, or deleted 11 | """ 12 | print("Clearing product cache") 13 | 14 | # Clear product list caches 15 | cache.delete_pattern('*product_list*') -------------------------------------------------------------------------------- /Video26/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video26/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | path('users/', views.UserListView.as_view()), 10 | ] 11 | 12 | router = DefaultRouter() 13 | router.register('orders', views.OrderViewSet) 14 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video26/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video26/drf_course/__init__.py -------------------------------------------------------------------------------- /Video26/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video26/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video26/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video26/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video26/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video26/requirements.txt -------------------------------------------------------------------------------- /Video27/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video27/api/__init__.py -------------------------------------------------------------------------------- /Video27/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video27/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | 8 | def ready(self): 9 | from . import signals 10 | -------------------------------------------------------------------------------- /Video27/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video27/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video27/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video27/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video27/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video27/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video27/api/signals.py: -------------------------------------------------------------------------------- 1 | from django.db.models.signals import post_save, post_delete 2 | from django.dispatch import receiver 3 | from api.models import Product 4 | from django.core.cache import cache 5 | 6 | 7 | @receiver([post_save, post_delete], sender=Product) 8 | def invalidate_product_cache(sender, instance, **kwargs): 9 | """ 10 | Invalidate product list caches when a product is created, updated, or deleted 11 | """ 12 | print("Clearing product cache") 13 | 14 | # Clear product list caches 15 | cache.delete_pattern('*product_list*') -------------------------------------------------------------------------------- /Video27/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video27/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | path('users/', views.UserListView.as_view()), 10 | ] 11 | 12 | router = DefaultRouter() 13 | router.register('orders', views.OrderViewSet) 14 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video27/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video27/drf_course/__init__.py -------------------------------------------------------------------------------- /Video27/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video27/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video27/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video27/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video27/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video27/requirements.txt -------------------------------------------------------------------------------- /Video28/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video28/api/__init__.py -------------------------------------------------------------------------------- /Video28/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video28/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | 8 | def ready(self): 9 | from . import signals 10 | -------------------------------------------------------------------------------- /Video28/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video28/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video28/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video28/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video28/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video28/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video28/api/signals.py: -------------------------------------------------------------------------------- 1 | from django.db.models.signals import post_save, post_delete 2 | from django.dispatch import receiver 3 | from api.models import Product 4 | from django.core.cache import cache 5 | 6 | 7 | @receiver([post_save, post_delete], sender=Product) 8 | def invalidate_product_cache(sender, instance, **kwargs): 9 | """ 10 | Invalidate product list caches when a product is created, updated, or deleted 11 | """ 12 | print("Clearing product cache") 13 | 14 | # Clear product list caches 15 | cache.delete_pattern('*product_list*') -------------------------------------------------------------------------------- /Video28/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) 28 | -------------------------------------------------------------------------------- /Video28/api/throttles.py: -------------------------------------------------------------------------------- 1 | from rest_framework.throttling import UserRateThrottle 2 | 3 | class BurstRateThrottle(UserRateThrottle): 4 | scope = 'burst' 5 | 6 | class SustainedRateThrottle(UserRateThrottle): 7 | scope = 'sustained' -------------------------------------------------------------------------------- /Video28/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view()), 9 | path('users/', views.UserListView.as_view()), 10 | ] 11 | 12 | router = DefaultRouter() 13 | router.register('orders', views.OrderViewSet) 14 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video28/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video28/drf_course/__init__.py -------------------------------------------------------------------------------- /Video28/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video28/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video28/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video28/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video28/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video28/requirements.txt -------------------------------------------------------------------------------- /Video29/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video29/api/__init__.py -------------------------------------------------------------------------------- /Video29/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem, User, Product 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) 14 | admin.site.register(User) 15 | admin.site.register(Product) -------------------------------------------------------------------------------- /Video29/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | 8 | def ready(self): 9 | from . import signals 10 | -------------------------------------------------------------------------------- /Video29/api/filters.py: -------------------------------------------------------------------------------- 1 | import django_filters 2 | from api.models import Product, Order 3 | from rest_framework import filters 4 | 5 | 6 | class InStockFilterBackend(filters.BaseFilterBackend): 7 | def filter_queryset(self, request, queryset, view): 8 | return queryset.filter(stock__gt=0) 9 | 10 | 11 | class ProductFilter(django_filters.FilterSet): 12 | class Meta: 13 | model = Product 14 | fields = { 15 | 'name': ['iexact', 'icontains'], 16 | 'price': ['exact', 'lt', 'gt', 'range'] 17 | } 18 | 19 | class OrderFilter(django_filters.FilterSet): 20 | created_at = django_filters.DateFilter(field_name='created_at__date') 21 | class Meta: 22 | model = Order 23 | fields = { 24 | 'status': ['exact'], 25 | 'created_at': ['lt', 'gt', 'exact'] 26 | } -------------------------------------------------------------------------------- /Video29/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video29/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video29/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video29/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video29/api/paginate.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | page = 1 4 | hasNextPage = True 5 | 6 | while hasNextPage: 7 | endpoint = "http://localhost:8000/products/" 8 | params = {'page': page} 9 | data = requests.get(endpoint, params=params).json() 10 | print(data['next']) 11 | if not data['next']: 12 | hasNextPage = False 13 | page += 1 -------------------------------------------------------------------------------- /Video29/api/signals.py: -------------------------------------------------------------------------------- 1 | from django.db.models.signals import post_save, post_delete 2 | from django.dispatch import receiver 3 | from api.models import Product 4 | from django.core.cache import cache 5 | 6 | 7 | @receiver([post_save, post_delete], sender=Product) 8 | def invalidate_product_cache(sender, instance, **kwargs): 9 | """ 10 | Invalidate product list caches when a product is created, updated, or deleted 11 | """ 12 | print("Clearing product cache") 13 | 14 | # Clear product list caches 15 | cache.delete_pattern('*product_list*') -------------------------------------------------------------------------------- /Video29/api/throttles.py: -------------------------------------------------------------------------------- 1 | from rest_framework.throttling import UserRateThrottle 2 | 3 | class BurstRateThrottle(UserRateThrottle): 4 | scope = 'burst' 5 | 6 | class SustainedRateThrottle(UserRateThrottle): 7 | scope = 'sustained' -------------------------------------------------------------------------------- /Video29/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | from rest_framework.routers import DefaultRouter 4 | 5 | urlpatterns = [ 6 | path('products/', views.ProductListCreateAPIView.as_view()), 7 | path('products/info/', views.ProductInfoAPIView.as_view()), 8 | path('products//', views.ProductDetailAPIView.as_view(), name='product-detail'), 9 | path('users/', views.UserListView.as_view()), 10 | ] 11 | 12 | router = DefaultRouter() 13 | router.register('orders', views.OrderViewSet) 14 | urlpatterns += router.urls -------------------------------------------------------------------------------- /Video29/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video29/drf_course/__init__.py -------------------------------------------------------------------------------- /Video29/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video29/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from rest_framework_simplejwt.views import ( 4 | TokenObtainPairView, 5 | TokenRefreshView, 6 | ) 7 | from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView 8 | 9 | urlpatterns = [ 10 | path('admin/', admin.site.urls), 11 | path('', include('api.urls')), 12 | path('silk/', include('silk.urls', namespace='silk')), 13 | path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), 14 | path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), 15 | 16 | path('api/schema/', SpectacularAPIView.as_view(), name='schema'), 17 | # Optional UI: 18 | path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), 19 | path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), 20 | ] 21 | -------------------------------------------------------------------------------- /Video29/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video29/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video29/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video29/requirements.txt -------------------------------------------------------------------------------- /Video3/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video3/api/__init__.py -------------------------------------------------------------------------------- /Video3/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video3/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video3/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video3/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video3/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video3/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video3/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video3/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.product_list), 6 | path('products//', views.product_detail), 7 | path('orders/', views.order_list), 8 | ] 9 | -------------------------------------------------------------------------------- /Video3/api/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import get_object_or_404 2 | from api.serializers import ProductSerializer, OrderSerializer 3 | from api.models import Product, Order, OrderItem 4 | from rest_framework.response import Response 5 | from rest_framework.decorators import api_view 6 | 7 | 8 | @api_view(['GET']) 9 | def product_list(request): 10 | products = Product.objects.all() 11 | serializer = ProductSerializer(products, many=True) 12 | return Response(serializer.data) 13 | 14 | @api_view(['GET']) 15 | def product_detail(request, pk): 16 | product = get_object_or_404(Product, pk=pk) 17 | serializer = ProductSerializer(product) 18 | return Response(serializer.data) 19 | 20 | @api_view(['GET']) 21 | def order_list(request): 22 | orders = Order.objects.all() 23 | serializer = OrderSerializer(orders, many=True) 24 | return Response(serializer.data) 25 | -------------------------------------------------------------------------------- /Video3/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video3/drf_course/__init__.py -------------------------------------------------------------------------------- /Video3/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video3/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')) 7 | ] 8 | -------------------------------------------------------------------------------- /Video3/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video3/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video3/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video3/requirements.txt -------------------------------------------------------------------------------- /Video4/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video4/api/__init__.py -------------------------------------------------------------------------------- /Video4/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video4/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video4/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video4/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video4/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video4/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video4/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video4/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.product_list), 6 | path('products/info/', views.product_info), 7 | path('products//', views.product_detail), 8 | path('orders/', views.order_list), 9 | ] 10 | -------------------------------------------------------------------------------- /Video4/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from django.shortcuts import get_object_or_404 3 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 4 | from api.models import Product, Order, OrderItem 5 | from rest_framework.response import Response 6 | from rest_framework.decorators import api_view 7 | 8 | 9 | @api_view(['GET']) 10 | def product_list(request): 11 | products = Product.objects.all() 12 | serializer = ProductSerializer(products, many=True) 13 | return Response(serializer.data) 14 | 15 | @api_view(['GET']) 16 | def product_detail(request, pk): 17 | product = get_object_or_404(Product, pk=pk) 18 | serializer = ProductSerializer(product) 19 | return Response(serializer.data) 20 | 21 | @api_view(['GET']) 22 | def order_list(request): 23 | orders = Order.objects.all() 24 | serializer = OrderSerializer(orders, many=True) 25 | return Response(serializer.data) 26 | 27 | @api_view(['GET']) 28 | def product_info(request): 29 | products = Product.objects.all() 30 | serializer = ProductInfoSerializer({ 31 | 'products': products, 32 | 'count': len(products), 33 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 34 | }) 35 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video4/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video4/drf_course/__init__.py -------------------------------------------------------------------------------- /Video4/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video4/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')) 7 | ] 8 | -------------------------------------------------------------------------------- /Video4/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video4/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video4/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video4/requirements.txt -------------------------------------------------------------------------------- /Video5/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video5/api/__init__.py -------------------------------------------------------------------------------- /Video5/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video5/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video5/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video5/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video5/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video5/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video5/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video5/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.product_list), 6 | path('products/info/', views.product_info), 7 | path('products//', views.product_detail), 8 | path('orders/', views.order_list), 9 | ] 10 | -------------------------------------------------------------------------------- /Video5/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from django.shortcuts import get_object_or_404 3 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 4 | from api.models import Product, Order, OrderItem 5 | from rest_framework.response import Response 6 | from rest_framework.decorators import api_view 7 | 8 | 9 | @api_view(['GET']) 10 | def product_list(request): 11 | products = Product.objects.all() 12 | serializer = ProductSerializer(products, many=True) 13 | return Response(serializer.data) 14 | 15 | @api_view(['GET']) 16 | def product_detail(request, pk): 17 | product = get_object_or_404(Product, pk=pk) 18 | serializer = ProductSerializer(product) 19 | return Response(serializer.data) 20 | 21 | @api_view(['GET']) 22 | def order_list(request): 23 | orders = Order.objects.prefetch_related('items__product') 24 | serializer = OrderSerializer(orders, many=True) 25 | return Response(serializer.data) 26 | 27 | @api_view(['GET']) 28 | def product_info(request): 29 | products = Product.objects.all() 30 | serializer = ProductInfoSerializer({ 31 | 'products': products, 32 | 'count': len(products), 33 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 34 | }) 35 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video5/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video5/drf_course/__init__.py -------------------------------------------------------------------------------- /Video5/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video5/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video5/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video5/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video5/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video5/requirements.txt -------------------------------------------------------------------------------- /Video6/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video6/api/__init__.py -------------------------------------------------------------------------------- /Video6/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /Video6/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video6/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video6/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video6/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video6/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video6/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video6/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListAPIView.as_view()), 6 | path('products/info/', views.product_info), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | ] 10 | -------------------------------------------------------------------------------- /Video6/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from django.shortcuts import get_object_or_404 3 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 4 | from api.models import Product, Order, OrderItem 5 | from rest_framework.response import Response 6 | from rest_framework.decorators import api_view 7 | from rest_framework import generics 8 | 9 | 10 | class ProductListAPIView(generics.ListAPIView): 11 | queryset = Product.objects.exclude(stock__gt=0) 12 | serializer_class = ProductSerializer 13 | 14 | 15 | class ProductDetailAPIView(generics.RetrieveAPIView): 16 | queryset = Product.objects.all() 17 | serializer_class = ProductSerializer 18 | lookup_url_kwarg = 'product_id' 19 | 20 | 21 | class OrderListAPIView(generics.ListAPIView): 22 | queryset = Order.objects.prefetch_related('items__product') 23 | serializer_class = OrderSerializer 24 | 25 | 26 | @api_view(['GET']) 27 | def product_info(request): 28 | products = Product.objects.all() 29 | serializer = ProductInfoSerializer({ 30 | 'products': products, 31 | 'count': len(products), 32 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 33 | }) 34 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video6/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video6/drf_course/__init__.py -------------------------------------------------------------------------------- /Video6/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video6/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video6/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video6/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video6/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video6/requirements.txt -------------------------------------------------------------------------------- /Video7/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video7/api/__init__.py -------------------------------------------------------------------------------- /Video7/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) -------------------------------------------------------------------------------- /Video7/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video7/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video7/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video7/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video7/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video7/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /Video7/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListAPIView.as_view()), 6 | path('products/info/', views.product_info), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view()), 10 | ] 11 | -------------------------------------------------------------------------------- /Video7/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from django.shortcuts import get_object_or_404 3 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 4 | from api.models import Product, Order, OrderItem 5 | from rest_framework.response import Response 6 | from rest_framework.decorators import api_view 7 | from rest_framework import generics 8 | 9 | 10 | class ProductListAPIView(generics.ListAPIView): 11 | queryset = Product.objects.exclude(stock__gt=0) 12 | serializer_class = ProductSerializer 13 | 14 | 15 | class ProductDetailAPIView(generics.RetrieveAPIView): 16 | queryset = Product.objects.all() 17 | serializer_class = ProductSerializer 18 | lookup_url_kwarg = 'product_id' 19 | 20 | 21 | class OrderListAPIView(generics.ListAPIView): 22 | queryset = Order.objects.prefetch_related('items__product') 23 | serializer_class = OrderSerializer 24 | 25 | 26 | class UserOrderListAPIView(generics.ListAPIView): 27 | queryset = Order.objects.prefetch_related('items__product') 28 | serializer_class = OrderSerializer 29 | 30 | def get_queryset(self): 31 | qs = super().get_queryset() 32 | return qs.filter(user=self.request.user) 33 | 34 | 35 | @api_view(['GET']) 36 | def product_info(request): 37 | products = Product.objects.all() 38 | serializer = ProductInfoSerializer({ 39 | 'products': products, 40 | 'count': len(products), 41 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 42 | }) 43 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video7/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video7/drf_course/__init__.py -------------------------------------------------------------------------------- /Video7/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video7/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video7/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video7/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video7/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video7/requirements.txt -------------------------------------------------------------------------------- /Video8/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video8/api/__init__.py -------------------------------------------------------------------------------- /Video8/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) -------------------------------------------------------------------------------- /Video8/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video8/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video8/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video8/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video8/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video8/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 28 | -------------------------------------------------------------------------------- /Video8/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListAPIView.as_view()), 6 | path('products/info/', views.product_info), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video8/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 3 | from api.models import Product, Order, OrderItem 4 | from rest_framework.response import Response 5 | from rest_framework.decorators import api_view 6 | from rest_framework import generics 7 | from rest_framework.permissions import IsAuthenticated 8 | 9 | class ProductListAPIView(generics.ListAPIView): 10 | queryset = Product.objects.exclude(stock__gt=0) 11 | serializer_class = ProductSerializer 12 | 13 | 14 | class ProductDetailAPIView(generics.RetrieveAPIView): 15 | queryset = Product.objects.all() 16 | serializer_class = ProductSerializer 17 | lookup_url_kwarg = 'product_id' 18 | 19 | 20 | class OrderListAPIView(generics.ListAPIView): 21 | queryset = Order.objects.prefetch_related('items__product') 22 | serializer_class = OrderSerializer 23 | 24 | 25 | class UserOrderListAPIView(generics.ListAPIView): 26 | queryset = Order.objects.prefetch_related('items__product') 27 | serializer_class = OrderSerializer 28 | permission_classes = [IsAuthenticated] 29 | 30 | def get_queryset(self): 31 | qs = super().get_queryset() 32 | return qs.filter(user=self.request.user) 33 | 34 | 35 | @api_view(['GET']) 36 | def product_info(request): 37 | products = Product.objects.all() 38 | serializer = ProductInfoSerializer({ 39 | 'products': products, 40 | 'count': len(products), 41 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 42 | }) 43 | return Response(serializer.data) -------------------------------------------------------------------------------- /Video8/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video8/drf_course/__init__.py -------------------------------------------------------------------------------- /Video8/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video8/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video8/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video8/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video8/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video8/requirements.txt -------------------------------------------------------------------------------- /Video9 & 10/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video9 & 10/api/__init__.py -------------------------------------------------------------------------------- /Video9 & 10/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from api.models import Order, OrderItem 3 | 4 | # Register your models here. 5 | class OrderItemInline(admin.TabularInline): 6 | model = OrderItem 7 | 8 | class OrderAdmin(admin.ModelAdmin): 9 | inlines = [ 10 | OrderItemInline 11 | ] 12 | 13 | admin.site.register(Order, OrderAdmin) -------------------------------------------------------------------------------- /Video9 & 10/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /Video9 & 10/api/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video9 & 10/api/management/commands/__init__.py -------------------------------------------------------------------------------- /Video9 & 10/api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video9 & 10/api/migrations/__init__.py -------------------------------------------------------------------------------- /Video9 & 10/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from api.models import Order, User 3 | from django.urls import reverse 4 | from rest_framework import status 5 | 6 | # Create your tests here. 7 | class UserOrderTestCase(TestCase): 8 | def setUp(self): 9 | user1 = User.objects.create_user(username='user1', password='test') 10 | user2 = User.objects.create_user(username='user2', password='test') 11 | Order.objects.create(user=user1) 12 | Order.objects.create(user=user1) 13 | Order.objects.create(user=user2) 14 | Order.objects.create(user=user2) 15 | 16 | def test_user_order_endpoint_retrieves_only_authenticated_user_orders(self): 17 | user = User.objects.get(username='user2') 18 | self.client.force_login(user) 19 | response = self.client.get(reverse('user-orders')) 20 | 21 | assert response.status_code == status.HTTP_200_OK 22 | orders = response.json() 23 | self.assertTrue(all(order['user'] == user.id for order in orders)) 24 | 25 | def test_user_order_list_unauthenticated(self): 26 | response = self.client.get(reverse('user-orders')) 27 | self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 28 | -------------------------------------------------------------------------------- /Video9 & 10/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('products/', views.ProductListCreateAPIView.as_view()), 6 | path('products/info/', views.ProductInfoAPIView.as_view()), 7 | path('products//', views.ProductDetailAPIView.as_view()), 8 | path('orders/', views.OrderListAPIView.as_view()), 9 | path('user-orders/', views.UserOrderListAPIView.as_view(), name='user-orders'), 10 | ] 11 | -------------------------------------------------------------------------------- /Video9 & 10/api/views.py: -------------------------------------------------------------------------------- 1 | from django.db.models import Max 2 | from api.serializers import ProductSerializer, OrderSerializer, ProductInfoSerializer 3 | from api.models import Product, Order, OrderItem 4 | from rest_framework.response import Response 5 | from rest_framework.decorators import api_view 6 | from rest_framework import generics 7 | from rest_framework.permissions import IsAuthenticated 8 | from rest_framework.views import APIView 9 | 10 | 11 | class ProductListCreateAPIView(generics.ListCreateAPIView): 12 | queryset = Product.objects.all() 13 | serializer_class = ProductSerializer 14 | 15 | 16 | class ProductDetailAPIView(generics.RetrieveAPIView): 17 | queryset = Product.objects.all() 18 | serializer_class = ProductSerializer 19 | lookup_url_kwarg = 'product_id' 20 | 21 | 22 | class OrderListAPIView(generics.ListAPIView): 23 | queryset = Order.objects.prefetch_related('items__product') 24 | serializer_class = OrderSerializer 25 | 26 | 27 | class UserOrderListAPIView(generics.ListAPIView): 28 | queryset = Order.objects.prefetch_related('items__product') 29 | serializer_class = OrderSerializer 30 | permission_classes = [IsAuthenticated] 31 | 32 | def get_queryset(self): 33 | qs = super().get_queryset() 34 | return qs.filter(user=self.request.user) 35 | 36 | 37 | class ProductInfoAPIView(APIView): 38 | def get(self, request): 39 | products = Product.objects.all() 40 | serializer = ProductInfoSerializer({ 41 | 'products': products, 42 | 'count': len(products), 43 | 'max_price': products.aggregate(max_price=Max('price'))['max_price'] 44 | }) 45 | return Response(serializer.data) 46 | -------------------------------------------------------------------------------- /Video9 & 10/drf_course/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video9 & 10/drf_course/__init__.py -------------------------------------------------------------------------------- /Video9 & 10/drf_course/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for drf_course project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Video9 & 10/drf_course/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | 4 | urlpatterns = [ 5 | path('admin/', admin.site.urls), 6 | path('', include('api.urls')), 7 | path('silk/', include('silk.urls', namespace='silk')) 8 | ] 9 | -------------------------------------------------------------------------------- /Video9 & 10/drf_course/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for drf_course project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /Video9 & 10/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_course.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /Video9 & 10/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugbytes-io/drf-course-api/41cb0abbf1f5870b1840df8aa120dc92d38bfeb8/Video9 & 10/requirements.txt --------------------------------------------------------------------------------