From a901b8d54a824cbccbac2d620a6160d5b7460cf5 Mon Sep 17 00:00:00 2001 From: Andros Fenollosa Date: Tue, 22 Jun 2021 15:43:26 +0200 Subject: [PATCH] Add API --- app/api/__init__.py | 0 app/api/admin.py | 9 ++ app/api/apps.py | 6 ++ app/api/migrations/0001_initial.py | 24 +++++ app/api/migrations/__init__.py | 0 app/api/models.py | 15 +++ app/api/serializers.py | 9 ++ app/api/tests.py | 3 + app/api/views.py | 11 +++ app/web/__init__.py | 0 app/web/admin.py | 3 + app/web/apps.py | 6 ++ app/web/migrations/__init__.py | 0 app/web/templates/layouts/base.html | 26 ++++++ app/web/templates/pages/add-news.html | 10 ++ app/web/templates/pages/list.html | 12 +++ app/web/tests.py | 3 + app/web/views.py | 12 +++ db.sqlite3 | Bin 0 -> 135168 bytes hackernews/__init__.py | 0 hackernews/asgi.py | 16 ++++ hackernews/settings.py | 128 ++++++++++++++++++++++++++ hackernews/urls.py | 31 +++++++ hackernews/wsgi.py | 16 ++++ manage.py | 22 +++++ requirements.txt | 6 ++ 26 files changed, 368 insertions(+) create mode 100644 app/api/__init__.py create mode 100644 app/api/admin.py create mode 100644 app/api/apps.py create mode 100644 app/api/migrations/0001_initial.py create mode 100644 app/api/migrations/__init__.py create mode 100644 app/api/models.py create mode 100644 app/api/serializers.py create mode 100644 app/api/tests.py create mode 100644 app/api/views.py create mode 100644 app/web/__init__.py create mode 100644 app/web/admin.py create mode 100644 app/web/apps.py create mode 100644 app/web/migrations/__init__.py create mode 100644 app/web/templates/layouts/base.html create mode 100644 app/web/templates/pages/add-news.html create mode 100644 app/web/templates/pages/list.html create mode 100644 app/web/tests.py create mode 100644 app/web/views.py create mode 100644 db.sqlite3 create mode 100644 hackernews/__init__.py create mode 100644 hackernews/asgi.py create mode 100644 hackernews/settings.py create mode 100644 hackernews/urls.py create mode 100644 hackernews/wsgi.py create mode 100755 manage.py create mode 100644 requirements.txt diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/admin.py b/app/api/admin.py new file mode 100644 index 0000000..92b9b1c --- /dev/null +++ b/app/api/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from app.api.models import News + + +@admin.register(News) +class NewsAdmin(admin.ModelAdmin): + readonly_fields = ('votes',) + list_display = ('title', 'url') + diff --git a/app/api/apps.py b/app/api/apps.py new file mode 100644 index 0000000..24cf026 --- /dev/null +++ b/app/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'app.api' diff --git a/app/api/migrations/0001_initial.py b/app/api/migrations/0001_initial.py new file mode 100644 index 0000000..6ea824e --- /dev/null +++ b/app/api/migrations/0001_initial.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.4 on 2021-06-22 10:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='News', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=50)), + ('url', models.CharField(max_length=500)), + ('votes', models.IntegerField()), + ('created', models.DateTimeField(auto_now_add=True)), + ], + ), + ] diff --git a/app/api/migrations/__init__.py b/app/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/models.py b/app/api/models.py new file mode 100644 index 0000000..6364146 --- /dev/null +++ b/app/api/models.py @@ -0,0 +1,15 @@ +from django.db import models + + +class News(models.Model): + title = models.CharField(max_length=50) + url = models.CharField(max_length=500) + votes = models.IntegerField(default=0) + created = models.DateTimeField(auto_now_add=True) + + class Meta: + verbose_name = "News" + verbose_name_plural = "News" + + def __str__(self): + return self.title diff --git a/app/api/serializers.py b/app/api/serializers.py new file mode 100644 index 0000000..f34eb50 --- /dev/null +++ b/app/api/serializers.py @@ -0,0 +1,9 @@ +from app.api.models import News +from rest_framework import serializers + + +class NewsSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = News + fields = ['title', 'url', 'created'] + diff --git a/app/api/tests.py b/app/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/api/views.py b/app/api/views.py new file mode 100644 index 0000000..6b774d4 --- /dev/null +++ b/app/api/views.py @@ -0,0 +1,11 @@ +from app.api.models import News +from rest_framework import viewsets +from app.api.serializers import NewsSerializer + + +class NewsViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows News to be viewed or edited. + """ + queryset = News.objects.all() + serializer_class = NewsSerializer \ No newline at end of file diff --git a/app/web/__init__.py b/app/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/web/admin.py b/app/web/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/app/web/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/app/web/apps.py b/app/web/apps.py new file mode 100644 index 0000000..4473a6c --- /dev/null +++ b/app/web/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WebConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'app.web' diff --git a/app/web/migrations/__init__.py b/app/web/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/web/templates/layouts/base.html b/app/web/templates/layouts/base.html new file mode 100644 index 0000000..4a84b1e --- /dev/null +++ b/app/web/templates/layouts/base.html @@ -0,0 +1,26 @@ + + + + + {% block title %}{% endblock %} | Djanker News + + +
+ +
+
+

Djanker News

+ {% block main %}{% endblock %} +
+ + + \ No newline at end of file diff --git a/app/web/templates/pages/add-news.html b/app/web/templates/pages/add-news.html new file mode 100644 index 0000000..566549b --- /dev/null +++ b/app/web/templates/pages/add-news.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/app/web/templates/pages/list.html b/app/web/templates/pages/list.html new file mode 100644 index 0000000..ce60807 --- /dev/null +++ b/app/web/templates/pages/list.html @@ -0,0 +1,12 @@ +{% extends 'layouts/base.html' %} +{% block title %}Welcome{% endblock %} +{% block main %} + {% for item in news %} +
+

{{ item.title }}

+

+ Ver completo +

+
+ {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/app/web/tests.py b/app/web/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/web/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/web/views.py b/app/web/views.py new file mode 100644 index 0000000..21daad2 --- /dev/null +++ b/app/web/views.py @@ -0,0 +1,12 @@ +from django.shortcuts import render +from app.api.models import News + + +def home(request): + return render(request, 'pages/list.html', { + 'news': News.objects.all() + }) + + +def add_news(request): + return render(request, 'pages/add-news.html', {}) \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..9198ecd1a84133a201d6247ba522f09c324e040d GIT binary patch literal 135168 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 NPD{+l2`#N9{~K_uM?e4o literal 0 HcmV?d00001 diff --git a/hackernews/__init__.py b/hackernews/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hackernews/asgi.py b/hackernews/asgi.py new file mode 100644 index 0000000..5a7937c --- /dev/null +++ b/hackernews/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for hackernews project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hackernews.settings') + +application = get_asgi_application() diff --git a/hackernews/settings.py b/hackernews/settings.py new file mode 100644 index 0000000..08597f5 --- /dev/null +++ b/hackernews/settings.py @@ -0,0 +1,128 @@ +""" +Django settings for hackernews project. + +Generated by 'django-admin startproject' using Django 3.2.4. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.2/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure--l@xj@*d=v!20+)(7^m70&hguvmb#57)c+%-+$0i0i^eb2-goy' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rest_framework', + 'app.web', + 'app.api', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'hackernews.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'hackernews.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.2/topics/i18n/ + +LANGUAGE_CODE = 'es-es' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.2/howto/static-files/ + +STATIC_URL = '/static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/hackernews/urls.py b/hackernews/urls.py new file mode 100644 index 0000000..6856d1d --- /dev/null +++ b/hackernews/urls.py @@ -0,0 +1,31 @@ +"""hackernews URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from rest_framework import routers +from app.web.views import home, add_news +from app.api.views import NewsViewSet + +router = routers.DefaultRouter() +# Abrir esto -> http://127.0.0.1:8000/api/v1/news/ +router.register(r'v1/news', NewsViewSet) + +urlpatterns = [ + path('', home, name='list'), + path('add-news/', add_news, name='add-news'), + path('api/', include(router.urls)), + path('admin/', admin.site.urls), +] diff --git a/hackernews/wsgi.py b/hackernews/wsgi.py new file mode 100644 index 0000000..ec1285b --- /dev/null +++ b/hackernews/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for hackernews project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hackernews.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..86cfe72 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hackernews.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4affdbe --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +# Django +django +# Django Rest Framework +djangorestframework +markdown +django-filter \ No newline at end of file