{"id":20345805,"url":"https://github.com/izzypt/houses_api_challenge","last_synced_at":"2026-02-19T00:02:54.477Z","repository":{"id":151595600,"uuid":"580581229","full_name":"izzypt/houses_api_challenge","owner":"izzypt","description":"Exercise I had to solve for an interview.","archived":false,"fork":false,"pushed_at":"2023-01-23T19:23:28.000Z","size":284,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-23T04:39:21.501Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/izzypt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-20T23:08:09.000Z","updated_at":"2023-01-20T20:00:52.000Z","dependencies_parsed_at":"2023-04-18T21:46:31.710Z","dependency_job_id":null,"html_url":"https://github.com/izzypt/houses_api_challenge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/izzypt/houses_api_challenge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2Fhouses_api_challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2Fhouses_api_challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2Fhouses_api_challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2Fhouses_api_challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/izzypt","download_url":"https://codeload.github.com/izzypt/houses_api_challenge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2Fhouses_api_challenge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29599338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T22:25:43.180Z","status":"ssl_error","status_checked_at":"2026-02-18T22:25:42.766Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T22:09:50.133Z","updated_at":"2026-02-19T00:02:54.461Z","avatar_url":"https://github.com/izzypt.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exercise\n\n[Section 1 - The Problem](#TheProblem)\n\n[Section2 - Solution Process](#Solutionprocess)\n\n\n\u003cdiv align=\"left\"\u003e\n      \u003ca href=\"https://www.youtube.com/watch?v=Av_siN7ZDJs\"\u003e\n         \u003cimg src=\"https://img.youtube.com/vi/Av_siN7ZDJs/0.jpg\" style=\"width:100%;\"\u003e\n      \u003c/a\u003e\n\u003c/div\u003e\n\n\n\u003ca id=\"TheProblem\"\u003e\u003c/a\u003e\n\n# The problem \n\n  Properties are very special objects of our domain. Properties can have multiple Units.\n  Assume that properties have a unique name. Each property have an array of units, and\n  each unit can have the following values:\n  \n  - kitchen\n  - bathroom\n  - bedroom\n  - living-room\n\n## Objective\n\n1. Create a REST endpoint to add a new Property in one POST request:\n\n ###\n    {\n      \"name\":\"Yellow apartment\",\n      \"units\":[\"kitchen\",\"bathroom\",\"bedroom\"]\n    }\n    POST /properties\n    \n 2. Create an endpoint to delete a property.\n \n ###\n    {\n      \"name\":\"Yellow apartment\"\n    }\n    DELETE /properties\n    \n 3. Create an endpoint to fetch all Properties. The results should be sorted by the property name.\n \n ###\n    GET /properties\n    Response:\n    {\n      properties: [\n        {\n          \"name\":\"Yellow apartment\",\n          \"units\":[\"kitchen\",\"bathroom\",\"bedroom\"]\n        },\n        {\n          \"name\":\"Red apartment\",\n          \"units\":[\"kitchen\",\"bathroom\",\"bedroom\",\"bedroom\",\"living-room\"]\n        }\n       ]\n    }\n    \n 4. Create a frontend to list all properties using the API built on point 3.\n   \n### Optional\n\n5. Add to the frontend the possibility to add new properties;\n\n6. Add to the frontend the possibility to delete each property;\n\n7. Add on the GET properties backend endpoint the possibility to filter by the\nnumber of bedrooms. On the example showed on point 3, if we wanted to get all\nproperties with 2 bedrooms should return:\n\n###\n    {\n      properties: \n      [\n          {\n            \"name\":\"Red apartment\",\n            \"units\":[\"kitchen\",\"bathroom\",\"bedroom\",\"bedroom\",\"living-room\"]\n          }\n      ]\n    } \n\n\u003ca id=\"Solutionprocess\"\u003e\u003c/a\u003e\n    \n# Solution process \n\n  ### Starting backend\n  1 - Create virtual environment to keep our dependeciens isolated and avoid packages conflicts\n  \n    python3 -m venv venv\n    \n  2 - activate virtual env \n    \n     ubuntu/Mac -\u003e \"source venv/bin/activate\"\n     Win -\u003e \".\\venv\\Scripts\\activate\"\n     \n  3 - Install DJango \n  \n     $ python -m pip install Django\n     \n  4 - Install Django Rest framework\n  \n    $ pip install djangorestframework\n    \n  5 - Install corsheaders to request from  different domain than the one that served the web page (Frontend server != backend server)\n  \n    pip install django-cors-headers\n    \n  5 - Output a file to save/track our current packages\n  \n    $ pip freeze \u003e requirements.txt\n   Later we can install the same packages from it using : pip install -r requirements.txt\n    \n  6 - Start Django project\n   \n      $ django-admin startproject properties\n      \n ### Setting up Django\n  1 - Create an app for our API inside our project to separate it into different modules\n  \n      $ python manage.py startapp api \n\n  2 - Add Django rest framework and the api app we just created to our installed apps in properties/settings.py so Django can recognize it.\n  \n      INSTALLED_APPS = [\n        'corsheaders',\n        'api.apps.ApiConfig'\n        'rest_framework',\n        'django.contrib.admin',\n        'django.contrib.auth',\n        'django.contrib.contenttypes',\n        'django.contrib.sessions',\n        'django.contrib.messages',\n        'django.contrib.staticfiles',\n      ]\n      \n   3 - Insert corsheaders into our middleware\n   \n    MIDDLEWARE = \n    [\n      'django.middleware.security.SecurityMiddleware',\n      'django.contrib.sessions.middleware.SessionMiddleware',\n      'corsheaders.middleware.CorsMiddleware',\n      'django.middleware.common.CommonMiddleware',\n      'django.middleware.csrf.CsrfViewMiddleware',\n      'django.contrib.auth.middleware.AuthenticationMiddleware',\n      'django.contrib.messages.middleware.MessageMiddleware',\n      'django.middleware.clickjacking.XFrameOptionsMiddleware',\n    ]\n    \n   4 - Set a permission to our front-end server\n\n      CORS_ORIGIN_WHITELIST = [\n         'http://localhost:8080',\n      ]\n   \n      \n  ### Setup SQLite DB\n   1 - We will use SQlite for a small project. We need to make first migrations to setup the basic Django tables.\n   \n    $ python manage.py migrate\n    \n   2 - Create the models for the DB\n   \n        class Rooms(models.Model):\n            ROOM_CHOICES = [\n                ('kitchen', 'Kitchen'),\n                ('bathroom', 'Bathroom'),\n                ('bedroom', 'Bedroom'),\n                ('living-room', 'Living Room'),\n            ]\n            name = models.CharField(max_length=50, choices=ROOM_CHOICES,)\n\n            def __str__(self) -\u003e str:\n                return self.name\n\n        class House(models.Model):\n            name = models.CharField(max_length=50)\n\n            def __str__(self) -\u003e str:\n                return self.name\n\n        class House_Rooms(models.Model):\n            house = models.ForeignKey(House, on_delete=models.CASCADE)\n            room = models.ForeignKey(Rooms, on_delete=models.CASCADE)\n   \n   3 - Migrate the newly written models\n      \n      $ python manage.py makemigrations\n      $ python manage.py migrate\n      \n   ### Creating routes, views and serializers for our data\n   Now that we have our models, we can start creating routes and views to create and modify the data in the DB.\n   \n   1 - We will start by creating routes for our API in the urls.py of our api folder/app.\n\n      from django.urls import path\n      from . import views\n    \n      urlpatterns = [\n          path('houses', name='getHouses'),\n          path('house/add', name='addHouse'),\n          path('house/delete', name='deleteHouse'),\n          path('house/update', name='updateHouse')\n      ]\n      \n   2 - Now that we have the routes, we need some views , to handle what we will do once a user hits that point.\n   \n      from .models import House, Rooms , House_Rooms\n      from .serializers import HouseSerializer, RoomSerializer\n      from django.shortcuts import get_object_or_404\n      from django.http import HttpResponse\n      from rest_framework.response import Response\n      from rest_framework.decorators import api_view\n      from rest_framework import status\n      import json\n\n      @api_view(['GET'])\n      def getData(request):\n          houses = House.objects.all().order_by('name') \n          serializer = HouseSerializer(houses, many=True)\n          return Response(serializer.data)\n\n      @api_view(['GET','DELETE'])\n      def deleteHouse(request):\n          # Get the house ID from the request\n          house_id = request.data.get('house_id')\n\n          # Fetch Object\n          house = get_object_or_404(House, pk=house_id)\n\n          # Delete it\n          house.delete()\n          return Response(status=status.HTTP_202_ACCEPTED)\n\n      @api_view(['POST'])\n      def addHouse(request):\n          # Get the data from the request\n          house_name = request.data.get('house_name')\n          room_names = request.data.get('room_names')\n\n          # Create a new House object\n          house = House.objects.create(name=house_name)\n\n          # Create a new Rooms object for each room name\n          rooms = []\n          for room_name in room_names:\n              room = Rooms.objects.create(name=room_name)\n              rooms.append(room)\n\n          # Create a House_Rooms object for each room and associate it with the house\n          for room in rooms:\n              House_Rooms.objects.create(house=house, room=room)\n\n          return HttpResponse('House and rooms added successfully')\n\n      @api_view(['POST'])\n      def updateHouse(request):\n          # Get the data from the request\n          house_id = request.data.get('house_id')\n          house_name = request.data.get('house_name')\n          room_names = request.data.get('room_names')\n\n          # Get the House object to be updated\n          house = House.objects.get(pk=house_id)\n\n          # Update the house name\n          house.name = house_name\n          house.save()\n\n          # Delete the existing House_Rooms objects for this house\n          House_Rooms.objects.filter(house=house).delete()\n\n          # Create a new Rooms object for each room name\n          rooms = []\n          for room_name in room_names:\n              room = Rooms.objects.create(name=room_name)\n              rooms.append(room)\n\n          # Create a House_Rooms object for each room and associate it with the house\n          for room in rooms:\n              House_Rooms.objects.create(house=house, room=room)\n\n          return HttpResponse('House and rooms added successfully')\n          \n   3 - Now that we have our views, we need to assign them to each path:\n   \n    from django.urls import path\n    from . import views\n\n    urlpatterns = [\n        path('houses',views.getData, name='getData'),\n        path('addHouse',views.addHouse, name='addHouse'),\n        path('house/delete', views.deleteHouse, name='deleteHouse'),\n        path('house/update', views.updateHouse, name='updateHouse')\n    ]\n       \n\n   3 - At our properties main folder, in urls.py entry point (root urls file), include the urls from our api. This will include all routes we establish on our api folder.\n   \n      from django.urls import path, include\n\n      urlpatterns = [\n          path('admin/', admin.site.urls),\n          path('api/', include('api.urls'))\n      ]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Fhouses_api_challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fizzypt%2Fhouses_api_challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Fhouses_api_challenge/lists"}