Compare commits
10 Commits
b3d5853867
...
b622fd4121
| Author | SHA1 | Date | |
|---|---|---|---|
| b622fd4121 | |||
| 788eb99dcd | |||
| dcf99e5409 | |||
| cf8885ed14 | |||
| e04e991cfa | |||
| b46ec965e1 | |||
| 0793242dfe | |||
| da85e74860 | |||
| 567226684d | |||
| 1154b14e62 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -135,4 +135,10 @@ dmypy.json
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
cython_debug/
|
||||
|
||||
# npm
|
||||
node_modules/
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
0
apiv1/__init__.py
Normal file
0
apiv1/__init__.py
Normal file
3
apiv1/admin.py
Normal file
3
apiv1/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
5
apiv1/apps.py
Normal file
5
apiv1/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class Apiv1Config(AppConfig):
|
||||
name = 'apiv1'
|
||||
0
apiv1/migrations/__init__.py
Normal file
0
apiv1/migrations/__init__.py
Normal file
7
apiv1/models.py
Normal file
7
apiv1/models.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
from bookmarks.models import Bookmark
|
||||
|
||||
class BookmarkSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Bookmark
|
||||
fields = ['title', 'url', 'id']
|
||||
3
apiv1/tests.py
Normal file
3
apiv1/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
15
apiv1/urls.py
Normal file
15
apiv1/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.urls import include, path
|
||||
from rest_framework import routers, authtoken
|
||||
from rest_framework.authtoken import views as authtokenviews
|
||||
from . import views
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'bookmarks', views.BookmarkViewSet, basename='bookmark')
|
||||
|
||||
# Wire up our API using automatic URL routing.
|
||||
# Additionally, we include login URLs for the browsable API.
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
path('token/', authtokenviews.obtain_auth_token),
|
||||
]
|
||||
13
apiv1/views.py
Normal file
13
apiv1/views.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from rest_framework import viewsets
|
||||
|
||||
from . import models
|
||||
from bookmarks.models import Bookmark
|
||||
|
||||
class BookmarkViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = models.BookmarkSerializer
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(user = self.request.user)
|
||||
|
||||
def get_queryset(self):
|
||||
return Bookmark.objects.filter(user=self.request.user)
|
||||
6
bookmarks/templates/bookmarks/bookmark_form.html
Normal file
6
bookmarks/templates/bookmarks/bookmark_form.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<h1>Add a bookmark</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Save">
|
||||
</form>
|
||||
@@ -4,5 +4,6 @@ from . import views
|
||||
|
||||
app_name = 'bookmarks'
|
||||
urlpatterns = [
|
||||
path('', views.BookmarkListView.as_view(), name='bookmark-list')
|
||||
path('', views.BookmarkListView.as_view(), name='bookmark-list'),
|
||||
path('create', views.BookmarkCreate.as_view(), name='bookmark-create')
|
||||
]
|
||||
@@ -1,5 +1,7 @@
|
||||
from django.utils import timezone
|
||||
from .models import Bookmark
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic.list import ListView
|
||||
from django.views.generic import CreateView
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from .models import Bookmark
|
||||
@@ -8,7 +10,14 @@ class BookmarkListView(LoginRequiredMixin, ListView):
|
||||
model = Bookmark
|
||||
paginate_by = 20
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['now'] = timezone.now()
|
||||
return context
|
||||
def get_queryset(self):
|
||||
return Bookmark.objects.filter(user_id=self.request.user.id)
|
||||
|
||||
class BookmarkCreate(LoginRequiredMixin, CreateView):
|
||||
model = Bookmark
|
||||
fields = ['title','url']
|
||||
success_url = reverse_lazy('bookmarks:bookmark-list')
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.user = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
||||
3
forgetmenot/frontend/styles.scss
Normal file
3
forgetmenot/frontend/styles.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
@@ -32,12 +32,15 @@ ALLOWED_HOSTS = []
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'bookmarks.apps.BookmarksConfig',
|
||||
'apiv1.apps.Apiv1Config',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'rest_framework.authtoken'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -121,3 +124,17 @@ USE_TZ = True
|
||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.IsAuthenticated'
|
||||
],
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||
'PAGE_SIZE': 100,
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||
'rest_framework.authentication.TokenAuthentication',
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Forget me not</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
{% block content %} {% endblock %}
|
||||
|
||||
@@ -22,5 +22,6 @@ urlpatterns = [
|
||||
path('', views.home, name='home'),
|
||||
path('bookmarks/', include('bookmarks.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
path('accounts/', include('django.contrib.auth.urls'))
|
||||
path('accounts/', include('django.contrib.auth.urls')),
|
||||
path('api/v1/', include('apiv1.urls')),
|
||||
]
|
||||
|
||||
5130
frontend/package-lock.json
generated
Normal file
5130
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
frontend/package.json
Normal file
30
frontend/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"watch": "webpack --watch",
|
||||
"start": "webpack serve --open",
|
||||
"build": "webpack --env production"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"css-loader": "^5.2.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"mini-css-extract-plugin": "^1.5.1",
|
||||
"sass": "^1.32.12",
|
||||
"sass-loader": "^11.0.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"webpack": "^5.31.0",
|
||||
"webpack-cli": "^4.6.0",
|
||||
"webpack-dev-middleware": "^4.1.0",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
}
|
||||
1
frontend/src/styles.scss
Normal file
1
frontend/src/styles.scss
Normal file
@@ -0,0 +1 @@
|
||||
@import '../../forgetmenot/frontend/styles.scss';
|
||||
50
frontend/webpack.config.js
Normal file
50
frontend/webpack.config.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const path = require("path");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
|
||||
module.exports = (env) => {
|
||||
return {
|
||||
mode: env.production ? "production" : "development",
|
||||
entry: "./src/styles.scss",
|
||||
devtool: "inline-source-map",
|
||||
devServer: {
|
||||
contentBase: "./dist",
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
title: "Caching",
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: "[name].css",
|
||||
chunkFilename: "[id].css",
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: "[name].[contenthash].js",
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
clean: true,
|
||||
publicPath: "/",
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.s[ac]ss/i,
|
||||
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
moduleIds: "deterministic",
|
||||
runtimeChunk: "single",
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: "vendors",
|
||||
chunks: "all",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Reference in New Issue
Block a user