diff --git a/app/libros/__init__.py b/app/library/__init__.py similarity index 100% rename from app/libros/__init__.py rename to app/library/__init__.py diff --git a/app/libros/admin.py b/app/library/admin.py similarity index 100% rename from app/libros/admin.py rename to app/library/admin.py diff --git a/app/libros/apps.py b/app/library/apps.py similarity index 83% rename from app/libros/apps.py rename to app/library/apps.py index bccaec3..0eaf77a 100644 --- a/app/libros/apps.py +++ b/app/library/apps.py @@ -3,4 +3,4 @@ from django.apps import AppConfig class LibrosConfig(AppConfig): default_auto_field = "django.db.models.BigAutoField" - name = "app.libros" + name = "app.library" diff --git a/app/libros/migrations/0002_libros.py b/app/library/migrations/0001_initial.py similarity index 75% rename from app/libros/migrations/0002_libros.py rename to app/library/migrations/0001_initial.py index d8c9a73..d912c62 100644 --- a/app/libros/migrations/0002_libros.py +++ b/app/library/migrations/0001_initial.py @@ -1,17 +1,18 @@ -# Generated by Django 3.2.5 on 2021-07-09 16:33 +# Generated by Django 3.2.5 on 2021-07-14 14:16 from django.db import migrations, models class Migration(migrations.Migration): + initial = True + dependencies = [ - ('libros', '0001_initial'), ] operations = [ migrations.CreateModel( - name='Libros', + name='Book', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=255)), @@ -22,9 +23,9 @@ class Migration(migrations.Migration): ('updated_at', models.DateTimeField(auto_now=True)), ], options={ - 'verbose_name': 'Libro', - 'verbose_name_plural': 'Libros', - 'ordering': ('-created_at',), + 'verbose_name': 'Book', + 'verbose_name_plural': 'Books', + 'ordering': ('created_at',), }, ), ] diff --git a/app/libros/migrations/__init__.py b/app/library/migrations/__init__.py similarity index 100% rename from app/libros/migrations/__init__.py rename to app/library/migrations/__init__.py diff --git a/app/libros/models.py b/app/library/models.py similarity index 60% rename from app/libros/models.py rename to app/library/models.py index 9b1f313..e9810eb 100644 --- a/app/libros/models.py +++ b/app/library/models.py @@ -1,14 +1,9 @@ -# app/libros/models.py +# app/Library/models.py -from django.contrib.auth.models import AbstractUser from django.db import models -class CustomUser(AbstractUser): - pass - - -class Libros(models.Model): +class Book(models.Model): title = models.CharField(max_length=255) genre = models.CharField(max_length=255) year = models.CharField(max_length=4) @@ -17,9 +12,9 @@ class Libros(models.Model): updated_at = models.DateTimeField(auto_now=True) class Meta: - ordering = ("-created_at",) - verbose_name = "Libro" - verbose_name_plural = "Libros" + ordering = ("created_at",) + verbose_name = "Book" + verbose_name_plural = "Books" def __str__(self): return self.title diff --git a/app/libros/serializers.py b/app/library/serializers.py similarity index 59% rename from app/libros/serializers.py rename to app/library/serializers.py index d64b6d3..02fdbea 100644 --- a/app/libros/serializers.py +++ b/app/library/serializers.py @@ -1,12 +1,12 @@ -# app/libros/serializers.py +# app/Library/serializers.py from rest_framework import serializers -from .models import Libros +from .models import Book -class LibroSerializer(serializers.ModelSerializer): +class BookSerializer(serializers.ModelSerializer): class Meta: - model = Libros + model = Book fields = "__all__" read_only_fields = ( "id", diff --git a/app/library/urls.py b/app/library/urls.py new file mode 100644 index 0000000..90c0cbe --- /dev/null +++ b/app/library/urls.py @@ -0,0 +1,11 @@ +# app/Library/urls.py + +from django.urls import path +from app.library.views import ping, BookList, BookDetails + + +urlpatterns = [ + path("ping/", ping, name="ping"), + path("api/book/", BookList.as_view(), name="book_list"), + path("api/book//", BookDetails.as_view(), name="book_details"), +] diff --git a/app/libros/views.py b/app/library/views.py similarity index 63% rename from app/libros/views.py rename to app/library/views.py index 2b615ad..3bdab84 100644 --- a/app/libros/views.py +++ b/app/library/views.py @@ -1,11 +1,11 @@ -# app/libros/views.py +# app/Library/views.py from django.http import JsonResponse from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status -from .serializers import LibroSerializer -from .models import Libros +from .serializers import BookSerializer +from .models import Book def ping(request): @@ -13,42 +13,42 @@ def ping(request): return JsonResponse(data) -class LibrosList(APIView): +class BookList(APIView): def get(self, request): - libros = Libros.objects.all().order_by("created_at") - serializer = LibroSerializer(libros, many=True) + books = Book.objects.all() + serializer = BookSerializer(books, many=True) return Response(serializer.data, status=status.HTTP_200_OK) def post(self, request): - serializer = LibroSerializer(data=request.data) + serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) -class LibrosDetails(APIView): +class BookDetails(APIView): def get(self, request, pk): - libro = Libros.objects.filter(pk=pk).first() - if libro: - serializer = LibroSerializer(libro) + book = Book.objects.filter(pk=pk).first() + if book: + serializer = BookSerializer(book) return Response(serializer.data, status=status.HTTP_200_OK) return Response(status=status.HTTP_404_NOT_FOUND) def put(self, request, pk): - libro = Libros.objects.filter(pk=pk).first() - serializer = LibroSerializer(libro, data=request.data) + book = Book.objects.filter(pk=pk).first() + serializer = BookSerializer(book, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) - elif not libro: + elif not book: return Response(serializer.data, status=status.HTTP_404_NOT_FOUND) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk): - libro = Libros.objects.filter(pk=pk).first() - if libro: - serializer = LibroSerializer(libro) - libro.delete() + book = Book.objects.filter(pk=pk).first() + if book: + serializer = BookSerializer(book) + book.delete() return Response(serializer.data, status=status.HTTP_200_OK) return Response(status=status.HTTP_404_NOT_FOUND) diff --git a/app/libros/migrations/0001_initial.py b/app/libros/migrations/0001_initial.py deleted file mode 100644 index d29cdf4..0000000 --- a/app/libros/migrations/0001_initial.py +++ /dev/null @@ -1,44 +0,0 @@ -# Generated by Django 3.2.5 on 2021-07-04 20:09 - -import django.contrib.auth.models -import django.contrib.auth.validators -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), - ] - - operations = [ - migrations.CreateModel( - name='CustomUser', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), - ], - options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, - }, - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), - ] diff --git a/app/libros/urls.py b/app/libros/urls.py deleted file mode 100644 index d1bba4d..0000000 --- a/app/libros/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -# app/libros/urls.py - -from django.urls import path -from app.libros.views import * - - -urlpatterns = [ - path("ping/", ping, name="ping"), - path("api/libros/", LibrosList.as_view(), name="libros_list"), - path("api/libros//", LibrosDetails.as_view(), name="libros_details"), -] diff --git a/manage.py b/manage.py index 88c5155..dfe056c 100755 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ import sys def main(): """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyecto.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyect.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/proyecto/__init__.py b/proyect/__init__.py similarity index 100% rename from proyecto/__init__.py rename to proyect/__init__.py diff --git a/proyecto/asgi.py b/proyect/asgi.py similarity index 73% rename from proyecto/asgi.py rename to proyect/asgi.py index ba5272b..4f52d37 100644 --- a/proyecto/asgi.py +++ b/proyect/asgi.py @@ -1,5 +1,5 @@ """ -ASGI config for proyecto project. +ASGI config for proyect project. It exposes the ASGI callable as a module-level variable named ``application``. @@ -11,6 +11,6 @@ import os from django.core.asgi import get_asgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyecto.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyect.settings") application = get_asgi_application() diff --git a/proyecto/settings.py b/proyect/settings.py similarity index 93% rename from proyecto/settings.py rename to proyect/settings.py index d7d113d..d828b37 100644 --- a/proyecto/settings.py +++ b/proyect/settings.py @@ -1,5 +1,5 @@ """ -Django settings for proyecto project. +Django settings for proyect project. Generated by 'django-admin startproject' using Django 3.2.5. @@ -38,7 +38,7 @@ INSTALLED_APPS = [ "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", # nuevo - "app.libros", # nuevo + "app.library", # nuevo ] MIDDLEWARE = [ @@ -51,7 +51,7 @@ MIDDLEWARE = [ "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = "proyecto.urls" +ROOT_URLCONF = "proyect.urls" TEMPLATES = [ { @@ -69,7 +69,7 @@ TEMPLATES = [ }, ] -WSGI_APPLICATION = "proyecto.wsgi.application" +WSGI_APPLICATION = "proyect.wsgi.application" # Database @@ -109,11 +109,11 @@ LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" -USE_I18N = True +USE_I18N = False -USE_L10N = True +USE_L10N = False -USE_TZ = True +USE_TZ = False # Static files (CSS, JavaScript, Images) @@ -125,5 +125,3 @@ STATIC_URL = "/static/" # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" - -AUTH_USER_MODEL = "libros.CustomUser" diff --git a/proyect/urls.py b/proyect/urls.py new file mode 100644 index 0000000..7ac1ac8 --- /dev/null +++ b/proyect/urls.py @@ -0,0 +1,8 @@ +# proyect/urls.py + +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path("", include("app.library.urls")), +] diff --git a/proyecto/wsgi.py b/proyect/wsgi.py similarity index 73% rename from proyecto/wsgi.py rename to proyect/wsgi.py index 4893b71..82c3310 100644 --- a/proyecto/wsgi.py +++ b/proyect/wsgi.py @@ -1,5 +1,5 @@ """ -WSGI config for proyecto project. +WSGI config for proyect project. It exposes the WSGI callable as a module-level variable named ``application``. @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyecto.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proyect.settings") application = get_wsgi_application() diff --git a/proyecto/urls.py b/proyecto/urls.py deleted file mode 100644 index 19c11e9..0000000 --- a/proyecto/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -# proyecto/urls.py - -from django.contrib import admin -from django.urls import path, include - -urlpatterns = [ - path("admin/", admin.site.urls), - path("", include("app.libros.urls")), -] diff --git a/pytest.ini b/pytest.ini index b526df0..1324a85 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -DJANGO_SETTINGS_MODULE = proyecto.settings +DJANGO_SETTINGS_MODULE = proyect.settings # Opcional, pero recomendado python_files = tests.py test_*.py *_tests.py \ No newline at end of file diff --git a/tests/library/test_model.py b/tests/library/test_model.py new file mode 100644 index 0000000..8b3300f --- /dev/null +++ b/tests/library/test_model.py @@ -0,0 +1,28 @@ +# tests/Library/test_model.py + +import pytest +from app.library.models import Book + + +@pytest.mark.django_db +def test_book_model(): + + ## Given + book = Book( + title="The foundation", + genre="Science fiction", + year="1951", + author="Isaac Asimov", + ) + book.save() + + ## When + + ## Then + assert book.title == "The foundation" + assert book.genre == "Science fiction" + assert book.year == "1951" + assert book.author == "Isaac Asimov" + assert book.created_at + assert book.updated_at + assert str(book) == book.title diff --git a/tests/libros/test_serializers.py b/tests/library/test_serializers.py similarity index 75% rename from tests/libros/test_serializers.py rename to tests/library/test_serializers.py index 78c29cd..79de5f2 100644 --- a/tests/libros/test_serializers.py +++ b/tests/library/test_serializers.py @@ -1,6 +1,6 @@ -# tests/libros/test_serializers.py +# tests/Library/test_serializers.py -from app.libros.serializers import LibroSerializer +from app.library.serializers import BookSerializer def test_valid_libro_serializer(): @@ -10,7 +10,7 @@ def test_valid_libro_serializer(): "year": "1987", "author": "Ray Bradbury", } - serializer = LibroSerializer(data=valid_serializer_data) + serializer = BookSerializer(data=valid_serializer_data) assert serializer.is_valid() assert serializer.validated_data == valid_serializer_data assert serializer.data == valid_serializer_data @@ -19,10 +19,10 @@ def test_valid_libro_serializer(): def test_invalid_libro_serializer(): invalid_serializer_data = { - "title": "Soy Leyenda", + "title": "I am legend", "author": "Richard Matheson", } - serializer = LibroSerializer(data=invalid_serializer_data) + serializer = BookSerializer(data=invalid_serializer_data) assert not serializer.is_valid() assert serializer.validated_data == {} assert serializer.data == invalid_serializer_data diff --git a/tests/libros/test_views.py b/tests/library/test_views.py similarity index 54% rename from tests/libros/test_views.py rename to tests/library/test_views.py index 88d432b..8039571 100644 --- a/tests/libros/test_views.py +++ b/tests/library/test_views.py @@ -1,7 +1,7 @@ -# tests/libros/test_views.py +# tests/Library/test_views.py import pytest -from app.libros.models import Libros +from app.library.models import Book from django.urls import reverse @@ -9,15 +9,15 @@ from django.urls import reverse def test_add_book(client): # Given - libros = Libros.objects.all() - assert len(libros) == 0 + book = Book.objects.all() + assert len(book) == 0 # When resp = client.post( - reverse("libros_list"), + reverse("book_list"), { - "title": "El fin de la eternidad", - "genre": "Ciencia Ficción", + "title": "The End of Eternity", + "genre": "Sciencie Fiction", "author": "Isaac Asimov", "year": "1955", }, @@ -26,36 +26,36 @@ def test_add_book(client): # Then assert resp.status_code == 201 - assert resp.data["title"] == "El fin de la eternidad" + assert resp.data["title"] == "The End of Eternity" - libros = Libros.objects.all() - assert len(libros) == 1 + book = Book.objects.all() + assert len(book) == 1 @pytest.mark.django_db def test_get_single_book(client): # Given - libro = Libros.objects.create( - title="El fin de la eternidad", - genre="Ciencia Ficción", + book = Book.objects.create( + title="The End of Eternity", + genre="Sciencie Fiction", author="Isaac Asimov", year="1955", ) # When - resp = client.get(reverse("libros_details", kwargs={"pk": libro.id})) + resp = client.get(reverse("book_details", kwargs={"pk": book.id})) # Then assert resp.status_code == 200 - assert resp.data["title"] == "El fin de la eternidad" + assert resp.data["title"] == "The End of Eternity" @pytest.mark.django_db def test_get_single_book_incorrect_id(client): # When - resp = client.get(reverse("libros_details", kwargs={"pk": 99})) + resp = client.get(reverse("book_details", kwargs={"pk": 99})) # Then assert resp.status_code == 404 @@ -66,50 +66,50 @@ def test_get_all_books(client, faker): # Given def create_random_book(): - return Libros.objects.create( + return Book.objects.create( title=faker.name(), genre=faker.job(), author=faker.name_nonbinary(), year=faker.year(), ) - libro_1 = create_random_book() - libro_2 = create_random_book() + book_1 = create_random_book() + book_2 = create_random_book() # When - resp = client.get(reverse("libros_list")) + resp = client.get(reverse("book_list")) # Then assert resp.status_code == 200 - assert resp.data[0]["title"] == libro_1.title - assert resp.data[1]["title"] == libro_2.title + assert resp.data[0]["title"] == book_1.title + assert resp.data[1]["title"] == book_2.title @pytest.mark.django_db def test_remove_book(client): # Given - libro = Libros.objects.create( - title="El fin de la eternidad", - genre="Ciencia Ficción", + book = Book.objects.create( + title="The End of Eternity", + genre="Sciencie Fiction", author="Isaac Asimov", year="1955", ) ## Check exist - resp_detail = client.get(reverse("libros_details", kwargs={"pk": libro.id})) + resp_detail = client.get(reverse("book_details", kwargs={"pk": book.id})) assert resp_detail.status_code == 200 - assert resp_detail.data["title"] == "El fin de la eternidad" + assert resp_detail.data["title"] == "The End of Eternity" # When - resp_delete = client.delete(reverse("libros_details", kwargs={"pk": libro.id})) - resp_list = client.get(reverse("libros_list")) - rest_new_detail = client.get(reverse("libros_details", kwargs={"pk": libro.id})) + resp_delete = client.delete(reverse("book_details", kwargs={"pk": book.id})) + resp_list = client.get(reverse("book_list")) + rest_new_detail = client.get(reverse("book_details", kwargs={"pk": book.id})) # Then ## Check status delete assert resp_delete.status_code == 200 ## Check return delete - assert resp_delete.data["title"] == "El fin de la eternidad" + assert resp_delete.data["title"] == "The End of Eternity" ## Check status list assert resp_list.status_code == 200 ## Check not item list @@ -121,15 +121,15 @@ def test_remove_book(client): @pytest.mark.django_db def test_remove_book_incorrect_id(client): # Given - libro = Libros.objects.create( - title="El fin de la eternidad", - genre="Ciencia Ficción", + book = Book.objects.create( + title="The End of Eternity", + genre="Sciencie Fiction", author="Isaac Asimov", year="1955", ) # When - resp = client.delete(reverse("libros_details", kwargs={"pk": 99})) + resp = client.delete(reverse("book_details", kwargs={"pk": 99})) # Then assert resp.status_code == 404 @@ -139,19 +139,19 @@ def test_remove_book_incorrect_id(client): def test_update_book(client): # Given - libro = Libros.objects.create( - title="El fin de la eternidad", - genre="Ciencia Ficción", + book = Book.objects.create( + title="The End of Eternity", + genre="Sciencie Fiction", author="Isaac Asimov", year="1955", ) # When resp = client.put( - reverse("libros_details", kwargs={"pk": libro.id}), + reverse("book_details", kwargs={"pk": book.id}), { "title": "Dune", - "genre": "Ciencia Ficción", + "genre": "Sciencie Fiction", "author": "Frank Herbert", "year": "1965", }, @@ -161,40 +161,40 @@ def test_update_book(client): # Then assert resp.status_code == 200 assert resp.data["title"] == "Dune" - assert resp.data["genre"] == "Ciencia Ficción" + assert resp.data["genre"] == "Sciencie Fiction" assert resp.data["author"] == "Frank Herbert" assert resp.data["year"] == "1965" - resp_detail = client.get(reverse("libros_details", kwargs={"pk": libro.id})) + resp_detail = client.get(reverse("book_details", kwargs={"pk": book.id})) assert resp_detail.status_code == 200 assert resp_detail.data["title"] == "Dune" - assert resp_detail.data["genre"] == "Ciencia Ficción" + assert resp_detail.data["genre"] == "Sciencie Fiction" assert resp_detail.data["author"] == "Frank Herbert" assert resp_detail.data["year"] == "1965" @pytest.mark.django_db def test_update_book_incorrect_id(client): - resp = client.put(reverse("libros_details", kwargs={"pk": 99})) + resp = client.put(reverse("book_details", kwargs={"pk": 99})) assert resp.status_code == 404 @pytest.mark.django_db def test_update_book_invalid_json(client): # Given - libro = Libros.objects.create( - title="El fin de la eternidad", - genre="Ciencia Ficción", + book = Book.objects.create( + title="The End of Eternity", + genre="Sciencie Fiction", author="Isaac Asimov", year="1955", ) # When resp = client.put( - reverse("libros_details", kwargs={"pk": libro.id}), + reverse("book_details", kwargs={"pk": book.id}), { "foo": "Dune", - "boo": "Ciencia Ficción", + "boo": "Sciencie Fiction", }, content_type="application/json", ) diff --git a/tests/libros/test_model.py b/tests/libros/test_model.py deleted file mode 100644 index 79ce29f..0000000 --- a/tests/libros/test_model.py +++ /dev/null @@ -1,30 +0,0 @@ -# tests/libros/test_model.py - -import pytest - -from app.libros.models import Libros - - -@pytest.mark.django_db -def test_libros_model(): - - ## Given - # Creamos un nuevo libro en la base de datos - libro = Libros( - title="La fundación", - genre="Ciencia ficción", - year="1951", - author="Isaac Asimov", - ) - libro.save() - - ## When - - ## Then - assert libro.title == "La fundación" - assert libro.genre == "Ciencia ficción" - assert libro.year == "1951" - assert libro.author == "Isaac Asimov" - assert libro.created_at - assert libro.updated_at - assert str(libro) == libro.title diff --git a/tests/test_ejemplo.py b/tests/test_ejemplo.py deleted file mode 100644 index e351af8..0000000 --- a/tests/test_ejemplo.py +++ /dev/null @@ -1,3 +0,0 @@ -# Las funciones deben empezar por "test_" -def test_titulo(): - assert "canción de hielo y fuego" != "juego de tronos"