Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a27d06b0d0 |
@@ -12,4 +12,3 @@ node_modules/
|
|||||||
*.code-workspace
|
*.code-workspace
|
||||||
venv/
|
venv/
|
||||||
.venv/
|
.venv/
|
||||||
poetry.lock
|
|
||||||
+6
-8
@@ -27,8 +27,7 @@ audit:
|
|||||||
- pushes
|
- pushes
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- pip install pip==25.3
|
- pip install poetry==2.0.1
|
||||||
- pip install poetry==2.1.1
|
|
||||||
- poetry config virtualenvs.create false
|
- poetry config virtualenvs.create false
|
||||||
- poetry install --no-interaction --no-ansi
|
- poetry install --no-interaction --no-ansi
|
||||||
script:
|
script:
|
||||||
@@ -49,8 +48,7 @@ test:
|
|||||||
DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB"
|
DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB"
|
||||||
DB_HOST: postgres
|
DB_HOST: postgres
|
||||||
before_script:
|
before_script:
|
||||||
- pip install pip==25.3
|
- pip install poetry==2.0.1
|
||||||
- pip install poetry==2.1.1
|
|
||||||
- poetry config virtualenvs.create false
|
- poetry config virtualenvs.create false
|
||||||
- poetry install --no-interaction --no-ansi
|
- poetry install --no-interaction --no-ansi
|
||||||
script:
|
script:
|
||||||
@@ -93,8 +91,8 @@ publish:
|
|||||||
services:
|
services:
|
||||||
- docker:25-dind
|
- docker:25-dind
|
||||||
only:
|
only:
|
||||||
- main
|
- develop
|
||||||
- production
|
- master
|
||||||
script:
|
script:
|
||||||
- docker info
|
- docker info
|
||||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||||
@@ -105,7 +103,7 @@ deploy:dev:
|
|||||||
image: docker:25-cli
|
image: docker:25-cli
|
||||||
stage: deploy
|
stage: deploy
|
||||||
only:
|
only:
|
||||||
- main
|
- develop
|
||||||
environment:
|
environment:
|
||||||
name: dev
|
name: dev
|
||||||
url: http://api.dev.sahkoinsinoorikilta.fi
|
url: http://api.dev.sahkoinsinoorikilta.fi
|
||||||
@@ -127,7 +125,7 @@ deploy:production:
|
|||||||
stage: deploy
|
stage: deploy
|
||||||
image: docker:25-cli
|
image: docker:25-cli
|
||||||
only:
|
only:
|
||||||
- production
|
- master
|
||||||
environment:
|
environment:
|
||||||
name: production
|
name: production
|
||||||
url: https://api.sahkoinsinoorikilta.fi
|
url: https://api.sahkoinsinoorikilta.fi
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
python 3.12.9
|
|
||||||
poetry 2.1.1
|
|
||||||
+4
-4
@@ -1,11 +1,12 @@
|
|||||||
FROM python:3.12.9-slim-bullseye AS builder
|
FROM python:3.12.9-slim-bullseye AS builder
|
||||||
ENV PYTHONUNBUFFERED 1
|
ENV PYTHONUNBUFFERED 1
|
||||||
COPY . ./
|
COPY . ./
|
||||||
ENV POETRY_VERSION=2.1.1
|
|
||||||
RUN pip install pip==25.3
|
ENV POETRY_VERSION=2.0.1
|
||||||
|
|
||||||
RUN pip install "poetry==$POETRY_VERSION"
|
RUN pip install "poetry==$POETRY_VERSION"
|
||||||
RUN poetry self add poetry-plugin-export
|
RUN poetry self add poetry-plugin-export
|
||||||
RUN poetry export --without-hashes --format=requirements.txt --output requirements.txt
|
RUN poetry export --without-hashes > requirements.txt
|
||||||
|
|
||||||
FROM python:3.12.9-slim-bullseye AS server
|
FROM python:3.12.9-slim-bullseye AS server
|
||||||
|
|
||||||
@@ -22,7 +23,6 @@ ENV PYTHONUNBUFFERED=1 \
|
|||||||
PIP_DEFAULT_TIMEOUT=100
|
PIP_DEFAULT_TIMEOUT=100
|
||||||
|
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y build-essential
|
RUN apt-get update && apt-get install --no-install-recommends -y build-essential
|
||||||
RUN pip install pip==25.3
|
|
||||||
RUN pip install --no-deps -r requirements.txt
|
RUN pip install --no-deps -r requirements.txt
|
||||||
|
|
||||||
RUN python manage.py collectstatic --noinput
|
RUN python manage.py collectstatic --noinput
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Set up your SSH key authentication in GitLab Profile Settings. Then clone the re
|
|||||||
```bash
|
```bash
|
||||||
git clone git@gitlab.com:sahkoinsinoorikilta/vtmk/web2.0-backend.git
|
git clone git@gitlab.com:sahkoinsinoorikilta/vtmk/web2.0-backend.git
|
||||||
cd web2.0-backend
|
cd web2.0-backend
|
||||||
|
git checkout develop
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy env file for local use:
|
Copy env file for local use:
|
||||||
@@ -30,34 +31,24 @@ For depedencies and virtual environment, we use [poetry](https://python-poetry.o
|
|||||||
First install [python](https://wiki.python.org/moin/BeginnersGuide/Download). Then install poetry:
|
First install [python](https://wiki.python.org/moin/BeginnersGuide/Download). Then install poetry:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m pip install poetry==2.1.1
|
python -m pip install poetry==2.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Install dependencies with
|
The easiest integration with VSCode is to have poetry install virtual environment in project folder, configured with CMD
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
poetry install
|
python -m poetry config virtualenvs.in-project true
|
||||||
```
|
|
||||||
|
|
||||||
Poetry is configured to install dependencies in a virtual environment, so you should see `.venv` folder in repo root.
|
|
||||||
|
|
||||||
Activate virtual environment in shell
|
|
||||||
|
|
||||||
```bash
|
|
||||||
eval $(poetry env activate)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Node
|
### Node
|
||||||
|
|
||||||
We use Node.js for few development tasks, like linting.
|
We use Node.js for few development tasks, like linting. Easiest way to install Node is [nvm](https://github.com/nvm-sh/nvm). After installing install dependencies:
|
||||||
Easiest way to install Node is [nvm](https://github.com/nvm-sh/nvm).
|
|
||||||
After installing install dependencies:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Linting](#linting) for more info
|
TODO: List scripts
|
||||||
|
|
||||||
### Database
|
### Database
|
||||||
|
|
||||||
@@ -71,28 +62,18 @@ docker run --name sik.web.db -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postg
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Install dependencies with
|
Activate virtual environment in shell
|
||||||
|
|
||||||
|
```bash
|
||||||
|
eval $(python -m poetry env activate)
|
||||||
|
```
|
||||||
|
|
||||||
|
Install dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
poetry install
|
poetry install
|
||||||
```
|
```
|
||||||
|
|
||||||
and make sure you are using Python from your virutal environment.
|
|
||||||
|
|
||||||
Virtual environment can be activated with
|
|
||||||
|
|
||||||
```bash
|
|
||||||
eval $(poetry env activate)
|
|
||||||
```
|
|
||||||
|
|
||||||
and you verify correct Python executable with
|
|
||||||
|
|
||||||
```bash
|
|
||||||
which python
|
|
||||||
|
|
||||||
# should return path similar to {your-system path}/web2.0-backend/.venv/bin/python
|
|
||||||
```
|
|
||||||
|
|
||||||
### Initializing data
|
### Initializing data
|
||||||
|
|
||||||
Run the following `manage.py` commands to initialize a new database. Do not run these in production without thinking!
|
Run the following `manage.py` commands to initialize a new database. Do not run these in production without thinking!
|
||||||
@@ -128,11 +109,11 @@ Example of creating a feature branch:
|
|||||||
git checkout -b feature-branch-name
|
git checkout -b feature-branch-name
|
||||||
```
|
```
|
||||||
|
|
||||||
When your changes are ready and the code works without errors, submit a merge request to `main` in GitLab. Another developer reviews your changes and runs the merge. Feature branches should be closed on merge.
|
When your changes are ready and the code works without errors, submit a merge request to `develop` in GitLab. Another developer reviews your changes and runs the merge. Feature branches should be closed on merge.
|
||||||
|
|
||||||
Bugfixes do not need their own feature branches and can be pushed straight to `main`, but if the fix needs a notable amount of work, it should be done in a `bugfix` branch instead.
|
Bugfixes do not need their own feature branches and can be pushed straight to `develop`, but if the fix needs a notable amount of work, it should be done in a `bugfix` branch instead.
|
||||||
|
|
||||||
Merge requests to `main` should be reviewed by multiple developers. Only a moderator can accept merge requests to `production`.
|
Merge requests to `master` should be reviewed by multiple developers. Only a moderator can accept merge requests to `master`.
|
||||||
|
|
||||||
### Linting
|
### Linting
|
||||||
|
|
||||||
@@ -172,4 +153,4 @@ For more information about deployment check **[infra](https://gitlab.com/sahkoin
|
|||||||
|
|
||||||
## GitLab CI
|
## GitLab CI
|
||||||
|
|
||||||
All pushed changes go through the GitLab Continuous Integration, which consists of automated unit testing and linting. Make sure your changes pass both before merging to `main` or `production`.
|
All pushed changes go through the GitLab Continuous Integration, which consists of automated unit testing and linting. Make sure your changes pass both before merging to `develop` or `master`.
|
||||||
|
|||||||
+5
-15
@@ -4,27 +4,17 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- dbdata:/var/lib/postgresql/data
|
- dbdata:/var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- "5432:5432"
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=postgres
|
- POSTGRES_PASSWORD=postgres
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
environment:
|
image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend
|
||||||
- DEPLOY_ENV=local
|
env_file:
|
||||||
- HOST=localhost
|
- .env
|
||||||
- DEBUG=True
|
|
||||||
- SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
|
|
||||||
- DB_NAME=postgres
|
|
||||||
- DB_USER=postgres
|
|
||||||
- DB_PASSWD=postgres
|
|
||||||
- DB_HOST=db
|
|
||||||
- DB_PORT=5432
|
|
||||||
- EMAIL_API_KEY=
|
|
||||||
- GROUP_KEY=
|
|
||||||
- GOOGLE_CREDS='{}'
|
|
||||||
ports:
|
ports:
|
||||||
- 8000:8000
|
- "8000:8000"
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 14:48
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("kaehmy", "0011_delete_kaehmybaserole"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="baserole",
|
|
||||||
name="category",
|
|
||||||
field=models.CharField(
|
|
||||||
choices=[
|
|
||||||
("board", "Board"),
|
|
||||||
("corporate", "Corporate affairs"),
|
|
||||||
("freshman", "Freshmen"),
|
|
||||||
("international", "International"),
|
|
||||||
("siwa", "SIK's free time"),
|
|
||||||
("media", "Media"),
|
|
||||||
("tech", "Technology"),
|
|
||||||
("wellbeing", "Wellbeing"),
|
|
||||||
("sikpaja", "Sik-paja"),
|
|
||||||
("ceremonies", "Ceremonies"),
|
|
||||||
("studies", "Studies"),
|
|
||||||
("sosso", "Sössö magazine"),
|
|
||||||
("pota", "PoTa"),
|
|
||||||
("alumni", "Alumni relations"),
|
|
||||||
("n", "N"),
|
|
||||||
("others", "Others"),
|
|
||||||
],
|
|
||||||
default="others",
|
|
||||||
max_length=255,
|
|
||||||
verbose_name="Category",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="customrole",
|
|
||||||
name="baserole_ptr",
|
|
||||||
field=models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="kaehmy.baserole",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="presetrole",
|
|
||||||
name="baserole_ptr",
|
|
||||||
field=models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="kaehmy.baserole",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
+1
-6
@@ -3,13 +3,8 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from members.models import Member, Request, Payment
|
from members.models import Member, Request, Payment
|
||||||
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
class MemberAdmin(admin.ModelAdmin):
|
admin.site.register(Member)
|
||||||
search_fields = ("first_name", "last_name", "email", "POR")
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Member, MemberAdmin)
|
|
||||||
admin.site.register(Request)
|
admin.site.register(Request)
|
||||||
admin.site.register(Payment)
|
admin.site.register(Payment)
|
||||||
|
|
||||||
|
|||||||
Generated
+1925
File diff suppressed because it is too large
Load Diff
+36
-41
@@ -5,49 +5,44 @@ authors = [
|
|||||||
description = "Backend for sahkoinsinoorikilta.fi"
|
description = "Backend for sahkoinsinoorikilta.fi"
|
||||||
name = "web2.0-backend"
|
name = "web2.0-backend"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = "~3.12"
|
requires-python = ">=3.12"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[virtualenvs]
|
dependencies = [
|
||||||
create = true
|
"decorator (>=4.4.2,<5.0.0)",
|
||||||
in-project = true
|
"Django (>=4.2.19,<5.0.0)",
|
||||||
|
"django-app-namespace-template-loader (>=0.4.1,<1.0.0)",
|
||||||
[tool.poetry.dependencies]
|
"django-auditlog (>=2.1.1,<3.0.0)",
|
||||||
decorator = "^4.4.2"
|
"django-autocomplete-light (>=3.4.1,<4.0.0)",
|
||||||
Django = "^4.2.19"
|
"django-bootstrap3 (>=21.2.0,<22.0.0)",
|
||||||
django-app-namespace-template-loader = "^0.4.1"
|
"django-cors-headers (>=3.13.0,<4.0.0)",
|
||||||
django-auditlog = "^2.1.1"
|
"django-filter (>=22.1.0,<23.0.0)",
|
||||||
django-autocomplete-light = "^3.4.1"
|
"django-import-export (>=2.8.0,<3.0.0)",
|
||||||
django-bootstrap3 = "^21.2.0"
|
"django-modeltranslation (>=0.18.4,<1.0.0)",
|
||||||
django-cors-headers = "^3.13.0"
|
"django-phonenumber-field[phonenumbers] (>=6.4.0,<7.0.0)",
|
||||||
django-filter = "^22.1.0"
|
"django-polymorphic (>=3.1.0,<4.0.0)",
|
||||||
django-import-export = "^2.8.0"
|
"django-tables2 (>=2.4.1,<3.0.0)",
|
||||||
django-modeltranslation = "^0.18.4"
|
"djangorestframework (>=3.12.4,<4.0.0)",
|
||||||
django-phonenumber-field = {version = "^6.4.0", extras = ["phonenumbers"]}
|
"djangorestframework-simplejwt (>=5.2.0,<6.0.0)",
|
||||||
django-polymorphic = "^3.1.0"
|
"google-auth (>=2.9.1,<3.0.0)",
|
||||||
django-tables2 = "^2.4.1"
|
"google-api-python-client (>=2.54.0,<3.0.0)",
|
||||||
djangorestframework = "^3.12.4"
|
"gunicorn (>=20.1.0,<21.0.0)",
|
||||||
djangorestframework-simplejwt = "^5.5.0"
|
"jsonschema (>=4.9.0,<5.0.0)",
|
||||||
google-auth = "^2.9.1"
|
"Markdown (>=3.2.2,<4.0.0)",
|
||||||
google-api-python-client = "^2.54.0"
|
"openpyxl (>=2.6.4,<3.0.0)",
|
||||||
gunicorn = "^23.0.0"
|
"Pillow (>=10.0.0,<11.0.0)",
|
||||||
jsonschema = "^4.9.0"
|
"psycopg2-binary (>=2.9.3,<3.0.0)",
|
||||||
Markdown = "^3.2.2"
|
"pyexcel (>=0.7.0,<1.0.0)",
|
||||||
openpyxl = "^2.6.4"
|
"pyexcel-io (>=0.6.0,<1.0.0)",
|
||||||
Pillow = "^10.0.0"
|
"pyexcel-xlsx (>=0.6.0,<1.0.0)",
|
||||||
psycopg2-binary = "^2.9.3"
|
"python-dotenv (>=0.20.0,<1.0.0)",
|
||||||
pyexcel = "^0.7.0"
|
"requests (>=2.28.1,<3.0.0)",
|
||||||
pyexcel-io = "^0.6.0"
|
"sendgrid (>=6.7.0,<7.0.0)",
|
||||||
pyexcel-xlsx = "^0.6.0"
|
"sentry-sdk (>=1.4.3,<2.0.0)",
|
||||||
python-dotenv = "^0.20.0"
|
"six (>=1.12.0,<2.0.0)",
|
||||||
requests = "^2.28.1"
|
"uWSGI (>=2.0.28,<3.0.0)",
|
||||||
sendgrid = "^6.7.0"
|
"whitenoise (>=6.2.0,<7.0.0)",
|
||||||
sentry-sdk = "^2.24.1"
|
]
|
||||||
six = "^1.12.0"
|
|
||||||
uWSGI = "^2.0.28"
|
|
||||||
whitenoise = "^6.2.0"
|
|
||||||
pyjwt = "^2.9.0"
|
|
||||||
setuptools = "^80.9.0"
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
black = "^25.1.0"
|
black = "^25.1.0"
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
</p>
|
</p>
|
||||||
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
|
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>11.10.</strong> {% blocktrans %}Toimikuntablää$t @Kiltis{% endblocktrans %}</li>
|
|
||||||
<li><strong>23.10.</strong> {% blocktrans %}Deadline hallitusvirkoihin hakemiselle.{% endblocktrans %}</li>
|
<li><strong>23.10.</strong> {% blocktrans %}Deadline hallitusvirkoihin hakemiselle.{% endblocktrans %}</li>
|
||||||
<li><strong>24.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
|
<li><strong>24.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
|
||||||
<li><strong>6.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen ja toimikuntien puheenjohtajien valinta){% endblocktrans %}</li>
|
<li><strong>6.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen ja toimikuntien puheenjohtajien valinta){% endblocktrans %}</li>
|
||||||
@@ -77,15 +76,10 @@
|
|||||||
|
|
||||||
<input type="checkbox" required name="gdpr" value="1">
|
<input type="checkbox" required name="gdpr" value="1">
|
||||||
<span>{% blocktrans %}
|
<span>{% blocktrans %}
|
||||||
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Suomeksi/Tietosuojaseloste%20–%20Toimihenkilöksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
|
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%E2%80%93%20Toimihenkil%C3%B6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</span>
|
</span>
|
||||||
<br>
|
<br>
|
||||||
<input type="checkbox" name="kaehmybot" value="1" checked>
|
|
||||||
<span>{% blocktrans %}
|
|
||||||
Kähmybot saa lähettää hakemuksestani ilmoituksen killan telegramiin (hallitusvirkoihin hakiessa valitse kyllä).
|
|
||||||
{% endblocktrans %}
|
|
||||||
</span>
|
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
{% trans "Submit" %}
|
{% trans "Submit" %}
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
|
|
||||||
{{ challenge.message }}
|
{{ challenge.message }}
|
||||||
|
|
||||||
{% trans "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 12.2" %}.
|
{% trans "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 13.2" %}.
|
||||||
|
|
||||||
{% trans "Käy kurkkaamassa muutkin haasteet osoitteessa" %} {{ url }}
|
{% trans "Käy kurkkaamassa muutkin haasteet osoitteessa" %} {{ url }}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 14:48
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("contenttypes", "0002_remove_content_type_name"),
|
|
||||||
("webapp", "0082_delete_baserole"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="signup",
|
|
||||||
name="submit_id",
|
|
||||||
field=models.UUIDField(default=uuid.uuid4, editable=False, null=True),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="basewebhook",
|
|
||||||
name="polymorphic_ctype",
|
|
||||||
field=models.ForeignKey(
|
|
||||||
editable=False,
|
|
||||||
null=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="polymorphic_%(app_label)s.%(class)s_set+",
|
|
||||||
to="contenttypes.contenttype",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 15:19
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("webapp", "0083_signup_submit_id_alter_basewebhook_polymorphic_ctype"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="signup",
|
|
||||||
name="submit_id",
|
|
||||||
field=models.UUIDField(null=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 15:46
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("webapp", "0084_alter_signup_submit_id"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="signup",
|
|
||||||
name="submit_id",
|
|
||||||
field=models.CharField(null=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 15:51
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("webapp", "0085_alter_signup_submit_id"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="signup",
|
|
||||||
name="submit_id",
|
|
||||||
field=models.UUIDField(editable=False, null=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.24 on 2025-10-13 15:53
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("webapp", "0086_alter_signup_submit_id"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name="signup",
|
|
||||||
name="submit_id",
|
|
||||||
field=models.UUIDField(editable=False, null=True, unique=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -195,8 +195,6 @@ class Signup(models.Model):
|
|||||||
email = models.EmailField(blank=True, null=True)
|
email = models.EmailField(blank=True, null=True)
|
||||||
# Random unique identifier. Used for signup editing by the user.
|
# Random unique identifier. Used for signup editing by the user.
|
||||||
uuid = models.UUIDField(default=uuid4, editable=False)
|
uuid = models.UUIDField(default=uuid4, editable=False)
|
||||||
# Random unique identifier generated by browser upon opening signup form. Used to prevent duplicate signups.
|
|
||||||
submit_id = models.UUIDField(null=True, editable=False, unique=True)
|
|
||||||
deleted = models.BooleanField(default=False)
|
deleted = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ class SignupSerializer(serializers.ModelSerializer):
|
|||||||
source="signupForm", queryset=SignupForm.objects.all()
|
source="signupForm", queryset=SignupForm.objects.all()
|
||||||
)
|
)
|
||||||
list_name = serializers.CharField(read_only=True)
|
list_name = serializers.CharField(read_only=True)
|
||||||
submit_id = serializers.UUIDField(required=False)
|
|
||||||
|
|
||||||
def add_extra_fields(self, validated_data):
|
def add_extra_fields(self, validated_data):
|
||||||
questions = validated_data["signupForm"].questions
|
questions = validated_data["signupForm"].questions
|
||||||
@@ -35,7 +34,7 @@ class SignupSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Signup
|
model = Signup
|
||||||
fields = ("id", "submit_id", "signupForm_id", "answer", "list_name")
|
fields = ("id", "signupForm_id", "answer", "list_name")
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
"url": {
|
"url": {
|
||||||
"view_name": "signup-detail",
|
"view_name": "signup-detail",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""Webapp views."""
|
"""Webapp views."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import time
|
|
||||||
from jwt import decode
|
from jwt import decode
|
||||||
from jwt.exceptions import InvalidTokenError
|
from jwt.exceptions import InvalidTokenError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@@ -12,7 +11,6 @@ from django.views.decorators.http import require_http_methods
|
|||||||
from django_filters import rest_framework as filters
|
from django_filters import rest_framework as filters
|
||||||
from django.db.models import Prefetch
|
from django.db.models import Prefetch
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.db.utils import IntegrityError
|
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||||
@@ -214,14 +212,6 @@ class SignupViewSet(ModelViewSet):
|
|||||||
return self.partial_update(request, *args, **kwargs)
|
return self.partial_update(request, *args, **kwargs)
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
# Temporary manual duplicate check as submit_id uniqueness is not enforced in deployment database
|
|
||||||
if "submit_id" in request.data and Signup.objects.filter(
|
|
||||||
submit_id=request.data["submit_id"]
|
|
||||||
):
|
|
||||||
return JsonResponse(
|
|
||||||
status=200, data={"message": "The submission has already been received"}
|
|
||||||
)
|
|
||||||
|
|
||||||
id = request.data["signupForm_id"]
|
id = request.data["signupForm_id"]
|
||||||
try:
|
try:
|
||||||
answer = request.data["answer"]
|
answer = request.data["answer"]
|
||||||
@@ -236,10 +226,6 @@ class SignupViewSet(ModelViewSet):
|
|||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
status=404, data={"error": f"SignupForm {id} not found"}
|
status=404, data={"error": f"SignupForm {id} not found"}
|
||||||
)
|
)
|
||||||
except IntegrityError:
|
|
||||||
return JsonResponse(
|
|
||||||
status=200, data={"message": "The submission has already been received"}
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
status=404, data={"error": f"SignupForm {id} not found"}
|
status=404, data={"error": f"SignupForm {id} not found"}
|
||||||
|
|||||||
Reference in New Issue
Block a user