Compare commits

..

No commits in common. "ada9d99644fd855df17ad15b1ab7f2c99ac1afcc" and "369202476ee7f3f8a7964311ca3240d8b76af72c" have entirely different histories.

27 changed files with 53 additions and 280 deletions

View file

@ -6,4 +6,5 @@ UID=1000
GID=1000
DATABASE_ENGINE= postgresql_psycopg2
DATABASE_HOST=db
DATABASE_PORT=5432

2
.idea/misc.xml generated
View file

@ -5,5 +5,5 @@
<option name="enabledOnSave" value="true" />
<option name="sdkName" value="Python 3.13 (movie-night-py)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Remote Python 3.12.7 Docker (&lt;none&gt;:&lt;none&gt;)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (movie-night-py)" project-jdk-type="Python SDK" />
</project>

View file

@ -16,7 +16,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Remote Python 3.12.7 Docker (&lt;none&gt;:&lt;none&gt;)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.13 (movie-night-py)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

View file

@ -35,4 +35,4 @@ USER web
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "movienight.wsgi:application"]
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "djangodocker.wsgi:application"]

View file

@ -1,5 +0,0 @@
Movie Night API
=
Requirements:
- Docker

View file

@ -1,5 +1,5 @@
"""
ASGI config for movienight project.
ASGI config for djangodocker 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', 'movienight.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangodocker.settings')
application = get_asgi_application()

View file

@ -28,7 +28,6 @@ SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
DEBUG = bool(os.environ.get("DEBUG", default=0))
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "127.0.0.1").split(",")
CORS_ALLOWED_ORIGINS = ["http://localhost:3000"]
# Application definition
@ -43,14 +42,11 @@ INSTALLED_APPS = [
"rest_framework",
"rest_framework.authtoken",
"knox",
"movie_manager",
"corsheaders",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
@ -58,7 +54,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "movienight.urls"
ROOT_URLCONF = "djangodocker.urls"
TEMPLATES = [
{
@ -76,7 +72,7 @@ TEMPLATES = [
},
]
WSGI_APPLICATION = "movienight.wsgi.application"
WSGI_APPLICATION = "djangodocker.wsgi.application"
# Database

View file

@ -1,5 +1,5 @@
"""
URL configuration for movienight project.
URL configuration for djangodocker project.
"""
import knox
@ -11,14 +11,11 @@ from django.conf import settings
from rest_framework.routers import DefaultRouter
from users import views as user_views
from movie_manager import views as movie_views
from rest_framework.authtoken.views import obtain_auth_token
router = DefaultRouter()
router.register(r"api/users", user_views.UserViewSet)
router.register(r"api/groups", user_views.GroupViewSet)
router.register(r"api/movies", movie_views.MovieViewset)
router.register(r"api/lists", movie_views.MovieListViewset)
urlpatterns = [
path("", include(router.urls)),

View file

@ -1,5 +1,5 @@
"""
WSGI config for movienight project.
WSGI config for djangodocker 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', 'movienight.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangodocker.settings')
application = get_wsgi_application()

View file

@ -1,7 +1,6 @@
services:
db:
image: postgres:17
container_name: movienight-db
environment:
POSTGRES_DB: ${DATABASE_NAME}
POSTGRES_USER: ${DATABASE_USERNAME}
@ -11,23 +10,16 @@ services:
ports:
- "5432:5432"
volumes:
- movienight_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready", "-d", "$DATABASE_NAME"]
interval: 30s
timeout: 60s
retries: 5
start_period: 80s
- djangodocker_data:/var/lib/postgresql/data
api:
build: .
user: ${UID}:${GID}
container_name: movienight-api
container_name: djangodocker-api
ports:
- "8000:8000"
depends_on:
db:
condition: service_healthy
- db
environment:
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY}
DEBUG: ${DEBUG}
@ -48,4 +40,4 @@ services:
- /etc/group:/etc/group:ro
volumes:
movienight_data:
djangodocker_data:

View file

@ -5,16 +5,16 @@ set -e
read -p "What is the project's name? " -r PROJECT_NAME
if [ -z "$PROJECT_NAME" ]
then
PROJECT_NAME="movienight"
PROJECT_NAME="djangodocker"
fi
echo "===== UPDATING PROJECT NAME ====="
git ls-files | xargs sed -i "s/movienight/${PROJECT_NAME}/g"
git ls-files | xargs sed -i "s/djangodocker/${PROJECT_NAME}/g"
echo "Done!"
echo "===== UPDATING ENVIRONMENT ====="
cp .env.example .env
sed -i "s/movienight/${PROJECT_NAME}/g" ./.env
sed -i "s/djangodocker/${PROJECT_NAME}/g" ./.env
# SET DATABASE USERNAME
read -p "Enter a username for the database: " -r DATABASE_USERNAME
@ -30,10 +30,8 @@ then
DATABASE_PASSWORD=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 15)
fi
# WRITE VARIABLES TO .ENV FILE
SECRET_KEY=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 50)
{
echo "DATABASE_HOST=${PROJECT_NAME}-db"
echo "DATABASE_NAME=${PROJECT_NAME}"
echo "DATABASE_USERNAME=${DATABASE_USERNAME}"
echo "DATABASE_PASSWORD=${DATABASE_PASSWORD}"
@ -41,26 +39,15 @@ SECRET_KEY=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 50)
echo "DJANGO_SECRET_KEY=${SECRET_KEY}"
} >> .env
# RENAME PROJECT DIRECTORY
if [ "$PROJECT_NAME" != "movienight" ]; then
mv movienight "$PROJECT_NAME"
fi
mv djangodocker "$PROJECT_NAME"
echo "===== STARTING DOCKER ====="
docker compose up -d --build
echo "===== MIGRATING DATABASE ====="
docker exec -ti "${PROJECT_NAME}-api" ./manage.py migrate
docker exec -ti "${PROJECT_NAME}-api" ./manage.py migrate
echo "===== CREATING SUPERUSER ====="
docker exec -ti "${PROJECT_NAME}-api" ./manage.py createsuperuser
echo "===== COLLECTING STATIC FILES ====="
docker exec -ti "${PROJECT_NAME}-api" ./manage.py collectstatic
echo "===== RESTARTING DOCKER CONTAINERS ====="
docker compose restart
echo "===== CREATE SUPERUSER ====="
docker exec -ti "${PROJECT_NAME}-api" ./manage.py createsuperuser
echo "Success! Go to http://localhost:8000 to see API documentation."
git remote remove origin

View file

@ -6,7 +6,7 @@ import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'movienight.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangodocker.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,6 +0,0 @@
from django.apps import AppConfig
class MovieManagerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'movie_manager'

View file

@ -1,48 +0,0 @@
# Generated by Django 5.1.4 on 2025-03-31 04:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Movie',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('imdb_id', models.CharField(max_length=100)),
('year', models.IntegerField()),
('critic_score', models.CharField(max_length=500)),
('genre', models.CharField(max_length=100)),
('director', models.CharField(max_length=500)),
('actors', models.CharField(max_length=500)),
('plot', models.CharField(max_length=500)),
('poster', models.CharField(max_length=500)),
('last_watched', models.DateTimeField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('deleted_at', models.DateTimeField(blank=True, null=True)),
],
),
migrations.CreateModel(
name='MovieList',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('public', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('deleted_at', models.DateTimeField(blank=True, null=True)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View file

@ -1,26 +0,0 @@
# Generated by Django 5.1.4 on 2025-04-07 05:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('movie_manager', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='movie',
options={'ordering': ['title']},
),
migrations.AlterModelOptions(
name='movielist',
options={'ordering': ['name']},
),
migrations.AddField(
model_name='movielist',
name='movies',
field=models.ManyToManyField(to='movie_manager.movie'),
),
]

View file

@ -1,40 +0,0 @@
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Movie(models.Model):
class Meta:
ordering = ["title"]
title = models.CharField(max_length=100)
imdb_id = models.CharField(max_length=100)
year = models.IntegerField()
critic_score = models.CharField(max_length=500)
genre = models.CharField(max_length=100)
director = models.CharField(max_length=500)
actors = models.CharField(max_length=500)
plot = models.CharField(max_length=500)
poster = models.CharField(max_length=500)
last_watched = models.DateTimeField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
deleted_at = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.title
class MovieList(models.Model):
class Meta:
ordering = ["name"]
name = models.CharField(max_length=100)
public = models.BooleanField(default=False)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
movies = models.ManyToManyField(Movie)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
deleted_at = models.DateTimeField(null=True, blank=True)
def __str__(self):
return self.name

View file

@ -1,21 +0,0 @@
from itertools import count
from rest_framework import serializers
from movie_manager.models import Movie, MovieList
class MovieSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = '__all__'
class MovieListSerializer(serializers.ModelSerializer):
movie_count = serializers.SerializerMethodField()
class Meta:
model = MovieList
fields = ["id","name","owner","public", "movie_count"]
def get_movie_count(self, obj):
return len(obj.movies.all())

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,48 +0,0 @@
from django.http import HttpResponse, JsonResponse
from django.contrib.auth.models import User
from rest_framework import permissions, viewsets
from knox.auth import TokenAuthentication
from rest_framework.exceptions import NotFound
from movie_manager.models import Movie, MovieList
from movie_manager.serializers import MovieListSerializer, MovieSerializer
# Create your views here.
class MovieViewset(viewsets.ModelViewSet):
fields = '__all__'
queryset = Movie.objects.all().order_by("title")
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
serializer_class = MovieSerializer
class MovieListViewset(viewsets.ModelViewSet):
fields = '__all__'
queryset = MovieList.objects.all().order_by("name")
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
serializer_class = MovieListSerializer
def update(self, request, pk=None, *args, **kwargs):
movie_list = MovieList.objects.get(pk=pk)
movie_list.name = request.data.get('name')
movie_list.owner = User.objects.get(pk=request.data.get("owner"))
if request.data.get('movies'):
movie_ids = request.data.get('movies')
for movie_id in movie_ids:
try:
movie = Movie.objects.get(pk=movie_id)
movie_list.movies.add(movie)
except Movie.DoesNotExist:
raise NotFound(f"Movie {movie_id} does not exist")
removed_movies = Movie.objects.exclude(id__in=movie_ids)
for removed_movie in removed_movies:
removed_movie.delete()
movie_list.save()
return JsonResponse(MovieListSerializer(movie_list).data)

View file

View file

@ -5,4 +5,3 @@ markdown
django-filter
gunicorn==23.0.0
psycopg2-binary==2.9.10
django-cors-headers==4.7.0

View file

@ -2144,7 +2144,7 @@ function tokenize( selector, parseOnly ) {
// Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
// Otherwise, throw an error or return users
if ( parseOnly ) {
return soFar.length;
}
@ -2152,7 +2152,7 @@ function tokenize( selector, parseOnly ) {
return soFar ?
find.error( selector ) :
// Cache the tokens
// Cache the users
tokenCache( selector, groups ).slice( 0 );
}
@ -2655,7 +2655,7 @@ function select( selector, context, results, seed ) {
testContext( context.parentNode ) || context
) ) ) {
// If seed is empty or no tokens remain, we can return early
// If seed is empty or no users remain, we can return early
tokens.splice( i, 1 );
selector = seed.length && toSelector( tokens );
if ( !selector ) {

View file

@ -43,7 +43,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
var _default = function _default(XRegExp) {
/**
* Adds base support for Unicode matching:
* - Adds syntax `\p{..}` for matching Unicode tokens. Tokens can be inverted using `\P{..}` or
* - Adds syntax `\p{..}` for matching Unicode users. Tokens can be inverted using `\P{..}` or
* `\p{^..}`. Token names ignore case, spaces, hyphens, and underscores. You can omit the
* braces for token names that are a single letter (e.g. `\pL` or `PL`).
* - Adds flag A (astral), which enables 21-bit Unicode support.
@ -129,7 +129,7 @@ var _default = function _default(XRegExp) {
var _context2;
combined += (0, _concat["default"])(_context2 = "".concat(item.astral ? '|' : '', "[")).call(_context2, item.bmp, "]");
} // Astral Unicode tokens always match a code point, never a code unit
} // Astral Unicode users always match a code point, never a code unit
return isNegated ? "(?:(?!".concat(combined, ")(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[\0-\uFFFF]))") : "(?:".concat(combined, ")");
@ -154,7 +154,7 @@ var _default = function _default(XRegExp) {
var ERR_UNKNOWN_NAME = 'Unknown Unicode token ';
var ERR_UNKNOWN_REF = 'Unicode token missing data ';
var ERR_ASTRAL_ONLY = 'Astral mode required for Unicode token ';
var ERR_ASTRAL_IN_CLASS = 'Astral mode does not support Unicode tokens within character classes';
var ERR_ASTRAL_IN_CLASS = 'Astral mode does not support Unicode users within character classes';
var _match = (0, _slicedToArray2["default"])(match, 6),
fullToken = _match[0],
@ -221,7 +221,7 @@ var _default = function _default(XRegExp) {
leadChar: '\\'
});
/**
* Adds to the list of Unicode tokens that XRegExp regexes can match via `\p` or `\P`.
* Adds to the list of Unicode users that XRegExp regexes can match via `\p` or `\P`.
*
* @memberOf XRegExp
* @param {Array} data Objects with named character ranges. Each object may have properties
@ -239,7 +239,7 @@ var _default = function _default(XRegExp) {
* points. `inverseOf` can be used to avoid duplicating character data if a Unicode token is
* defined as the exact inverse of another token.
* @param {String} [typePrefix] Enables optionally using this type as a prefix for all of the
* provided Unicode tokens, e.g. if given `'Type'`, then `\p{TokenName}` can also be written
* provided Unicode users, e.g. if given `'Type'`, then `\p{TokenName}` can also be written
* as `\p{Type=TokenName}`.
* @example
*
@ -471,7 +471,7 @@ var fixed = {}; // Storage for regexes cached by `XRegExp.cache`
var regexCache = {}; // Storage for pattern details cached by the `XRegExp` constructor
var patternCache = {}; // Storage for regex syntax tokens added internally or by `XRegExp.addToken`
var patternCache = {}; // Storage for regex syntax users added internally or by `XRegExp.addToken`
var tokens = []; // Token scopes
@ -668,7 +668,7 @@ function copyRegex(regex, options) {
xregexpFlags = flagsToAdd ? clipDuplicates((0, _flags["default"])(xData) + flagsToAdd) : (0, _flags["default"])(xData);
}
} // Augment with `XRegExp.prototype` properties, but use the native `RegExp` constructor to avoid
// searching for special tokens. That would be wrong for regexes constructed by `RegExp`, and
// searching for special users. That would be wrong for regexes constructed by `RegExp`, and
// unnecessary for regexes constructed by `XRegExp` because the regex has already undergone the
// translation to native regex syntax
@ -706,16 +706,16 @@ function getContextualTokenSeparator(match, scope, flags) {
var precedingChar = match.input[match.index - 1];
var followingChar = match.input[matchEndPos];
if ( // No need to separate tokens if at the beginning or end of a group, before or after a
if ( // No need to separate users if at the beginning or end of a group, before or after a
// group, or before or after a `|`
/^[()|]$/.test(precedingChar) || /^[()|]$/.test(followingChar) || // No need to separate tokens if at the beginning or end of the pattern
match.index === 0 || matchEndPos === match.input.length || // No need to separate tokens if at the beginning of a noncapturing group or lookaround.
/^[()|]$/.test(precedingChar) || /^[()|]$/.test(followingChar) || // No need to separate users if at the beginning or end of the pattern
match.index === 0 || matchEndPos === match.input.length || // No need to separate users if at the beginning of a noncapturing group or lookaround.
// Looks only at the last 4 chars (at most) for perf when constructing long regexes.
/\(\?(?:[:=!]|<[=!])$/.test(match.input.substring(match.index - 4, match.index)) || // Avoid separating tokens when the following token is a quantifier
/\(\?(?:[:=!]|<[=!])$/.test(match.input.substring(match.index - 4, match.index)) || // Avoid separating users when the following token is a quantifier
isQuantifierNext(match.input, matchEndPos, flags)) {
return '';
} // Keep tokens separated. This avoids e.g. inadvertedly changing `\1 1` or `\1(?#)1` to `\11`.
// This also ensures all tokens remain as discrete atoms, e.g. it prevents converting the
} // Keep users separated. This avoids e.g. inadvertedly changing `\1 1` or `\1(?#)1` to `\11`.
// This also ensures all users remain as discrete atoms, e.g. it prevents converting the
// syntax error `(? :` into `(?:`.
@ -914,13 +914,13 @@ function registerFlag(flag) {
registeredFlags[flag] = true;
}
/**
* Runs built-in and custom regex syntax tokens in reverse insertion order at the specified
* Runs built-in and custom regex syntax users in reverse insertion order at the specified
* position, until a match is found.
*
* @private
* @param {String} pattern Original pattern from which an XRegExp object is being built.
* @param {String} flags Flags being used to construct the regex.
* @param {Number} pos Position to search for tokens within `pattern`.
* @param {Number} pos Position to search for users within `pattern`.
* @param {Number} scope Regex scope to apply: 'default' or 'class'.
* @param {Object} context Context object to use for token handler functions.
* @returns {Object} Object with properties `matchLength`, `output`, and `reparse`; or `null`.
@ -1055,14 +1055,14 @@ function XRegExp(pattern, flags) {
var applied = prepareFlags(pattern, flags);
var appliedPattern = applied.pattern;
var appliedFlags = (0, _flags["default"])(applied); // Use XRegExp's tokens to translate the pattern to a native regex pattern.
// `appliedPattern.length` may change on each iteration if tokens use `reparse`
var appliedFlags = (0, _flags["default"])(applied); // Use XRegExp's users to translate the pattern to a native regex pattern.
// `appliedPattern.length` may change on each iteration if users use `reparse`
while (pos < appliedPattern.length) {
do {
// Check for custom tokens at the current position
// Check for custom users at the current position
result = runTokens(appliedPattern, appliedFlags, pos, scope, context); // If the matched token used the `reparse` option, splice its output into the
// pattern before running tokens again at the same position
// pattern before running users again at the same position
if (result && result.reparse) {
appliedPattern = (0, _slice["default"])(appliedPattern).call(appliedPattern, 0, pos) + result.output + (0, _slice["default"])(appliedPattern).call(appliedPattern, pos + result.matchLength);
@ -1091,7 +1091,7 @@ function XRegExp(pattern, flags) {
patternCache[pattern][flags] = {
// Use basic cleanup to collapse repeated empty groups like `(?:)(?:)` to `(?:)`. Empty
// groups are sometimes inserted during regex transpilation in order to keep tokens
// groups are sometimes inserted during regex transpilation in order to keep users
// separated. However, more than one empty group in a row is never needed.
pattern: output.replace(/(?:\(\?:\))+/g, '(?:)'),
// Strip all but native flags
@ -1151,7 +1151,7 @@ XRegExp._pad4 = pad4;
* not required to trigger the token. This registers the flags, to prevent XRegExp from
* throwing an 'unknown flag' error when any of the flags are used.
* - `reparse` {Boolean} Whether the `handler` function's output should not be treated as
* final, and instead be reparseable by other tokens (including the current token). Allows
* final, and instead be reparseable by other users (including the current token). Allows
* token chaining or deferring.
* - `leadChar` {String} Single character that occurs at the beginning of any successful match
* of the token (not always applicable). This doesn't change the behavior of the token unless
@ -1204,7 +1204,7 @@ XRegExp.addToken = function (regex, handler, options) {
} finally {
_iterator2.f();
}
} // Add to the private list of syntax tokens
} // Add to the private list of syntax users
tokens.push({
@ -2035,7 +2035,7 @@ fixed.match = function (regex) {
return fixed.exec.call(regex, nullThrows(this));
};
/**
* Adds support for `${n}` (or `$<n>`) tokens for named and numbered backreferences in replacement
* Adds support for `${n}` (or `$<n>`) users for named and numbered backreferences in replacement
* text, and provides named backreferences to replacement functions as `arguments[0].name`. Also
* fixes browser bugs in replacement text syntax when performing a replacement using a nonregex
* search value, and the value of a replacement regex's `lastIndex` property during replacement
@ -2271,7 +2271,7 @@ fixed.split = function (separator, limit) {
separator.lastIndex = origLastIndex;
return output.length > limit ? (0, _slice["default"])(output).call(output, 0, limit) : output;
}; // ==--------------------------==
// Built-in syntax/flag tokens
// Built-in syntax/flag users
// ==--------------------------==
/*
@ -2310,7 +2310,7 @@ XRegExp.addToken(/\\u{([\dA-Fa-f]+)}/, function (match, scope, flags) {
if (code <= 0xFFFF) {
// Converting to \uNNNN avoids needing to escape the literal character and keep it
// separate from preceding tokens
// separate from preceding users
return "\\u".concat(pad4(hex(code)));
} // If `code` is between 0xFFFF and 0x10FFFF, require and defer to native handling

View file

@ -3,6 +3,7 @@ from django.contrib.auth.models import Group, User, AnonymousUser
from rest_framework import permissions, viewsets, status
from knox.auth import TokenAuthentication
from knox.views import LoginView as KnoxLoginView
from rest_framework.authentication import BasicAuthentication
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view