zmiany mariusza
This commit is contained in:
BIN
backend/formulas/.DS_Store
vendored
Normal file
BIN
backend/formulas/.DS_Store
vendored
Normal file
Binary file not shown.
0
backend/formulas/__init__.py
Normal file
0
backend/formulas/__init__.py
Normal file
BIN
backend/formulas/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
backend/formulas/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/__pycache__/apps.cpython-312.pyc
Normal file
BIN
backend/formulas/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/__pycache__/permissions.cpython-312.pyc
Normal file
BIN
backend/formulas/__pycache__/permissions.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/__pycache__/urls.cpython-312.pyc
Normal file
BIN
backend/formulas/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
3
backend/formulas/admin/__init__.py
Normal file
3
backend/formulas/admin/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .formula import FormulaAdmin
|
||||
from .symbol import SymbolAdmin
|
||||
from .category import FormulaCategoryAdmin
|
||||
BIN
backend/formulas/admin/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
backend/formulas/admin/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/admin/__pycache__/category.cpython-312.pyc
Normal file
BIN
backend/formulas/admin/__pycache__/category.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/admin/__pycache__/formula.cpython-312.pyc
Normal file
BIN
backend/formulas/admin/__pycache__/formula.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/admin/__pycache__/symbol.cpython-312.pyc
Normal file
BIN
backend/formulas/admin/__pycache__/symbol.cpython-312.pyc
Normal file
Binary file not shown.
8
backend/formulas/admin/category.py
Normal file
8
backend/formulas/admin/category.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from formulas.models.category import FormulaCategory
|
||||
|
||||
@admin.register(FormulaCategory)
|
||||
class FormulaCategoryAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "prefix", "name")
|
||||
ordering = ("prefix",)
|
||||
search_fields = ("name",)
|
||||
10
backend/formulas/admin/formula.py
Normal file
10
backend/formulas/admin/formula.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.contrib import admin
|
||||
from formulas.models.formula import Formula
|
||||
|
||||
@admin.register(Formula)
|
||||
class FormulaAdmin(admin.ModelAdmin):
|
||||
list_display = ("formula_id", "title", "code", "revision", "category")
|
||||
list_filter = ("category", "revision")
|
||||
search_fields = ("formula_id", "title", "code", "description")
|
||||
readonly_fields = ("code", "created_at")
|
||||
ordering = ("code",)
|
||||
BIN
backend/formulas/admin/formulaadmin.zip
Normal file
BIN
backend/formulas/admin/formulaadmin.zip
Normal file
Binary file not shown.
10
backend/formulas/admin/symbol.py
Normal file
10
backend/formulas/admin/symbol.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.contrib import admin
|
||||
from formulas.models.symbol import Symbol
|
||||
|
||||
@admin.register(Symbol)
|
||||
class SymbolAdmin(admin.ModelAdmin):
|
||||
list_display = ("symbol_id", "name", "unit", "code", "revision", "category")
|
||||
list_filter = ("category", "revision")
|
||||
search_fields = ("symbol_id", "name", "code", "description")
|
||||
readonly_fields = ("code",)
|
||||
ordering = ("code",)
|
||||
6
backend/formulas/apps.py
Normal file
6
backend/formulas/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class FormulasConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'formulas'
|
||||
65
backend/formulas/migrations/0001_initial.py
Normal file
65
backend/formulas/migrations/0001_initial.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Generated by Django 4.2 on 2025-06-22 11:14
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FormulaCategory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('prefix', models.PositiveIntegerField(unique=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Kategoria wzoru',
|
||||
'verbose_name_plural': 'Kategorie wzorów',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Symbol',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('symbol_id', models.CharField(max_length=10)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('unit', models.CharField(max_length=50)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('tags', models.JSONField(blank=True, default=list)),
|
||||
('revision', models.PositiveIntegerField(default=1)),
|
||||
('code', models.CharField(editable=False, max_length=10, unique=True)),
|
||||
('meta', models.TextField(blank=True)),
|
||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='formulas.formulacategory')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Formula',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('formula_id', models.CharField(max_length=100)),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('meta', models.TextField(blank=True)),
|
||||
('tags', models.JSONField(default=list)),
|
||||
('latex', models.TextField()),
|
||||
('raw_latex', models.TextField()),
|
||||
('variables', models.JSONField(default=list)),
|
||||
('calculator', models.CharField(max_length=100)),
|
||||
('revision', models.PositiveIntegerField(default=1)),
|
||||
('code', models.CharField(editable=False, max_length=10, unique=True)),
|
||||
('created_at', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='formulas.formulacategory')),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
30
backend/formulas/migrations/0002_favoriteformula.py
Normal file
30
backend/formulas/migrations/0002_favoriteformula.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# Generated by Django 4.2 on 2025-07-13 19:15
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('formulas', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FavoriteFormula',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('added_at', models.DateTimeField(auto_now_add=True)),
|
||||
('formula', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='formulas.formula')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Ulubiony wzór',
|
||||
'verbose_name_plural': 'Ulubione wzory',
|
||||
'unique_together': {('user', 'formula')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2 on 2025-07-26 08:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('formulas', '0002_favoriteformula'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='formula',
|
||||
name='variables',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='formula',
|
||||
name='symbols',
|
||||
field=models.ManyToManyField(blank=True, related_name='formulas', to='formulas.symbol'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 4.2 on 2025-08-07 07:57
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('formulas', '0003_remove_formula_variables_formula_symbols'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='formula',
|
||||
name='code',
|
||||
field=models.CharField(max_length=10, unique=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='formula',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='formula',
|
||||
name='symbols',
|
||||
field=models.ManyToManyField(related_name='formulas', to='formulas.symbol'),
|
||||
),
|
||||
]
|
||||
0
backend/formulas/migrations/__init__.py
Normal file
0
backend/formulas/migrations/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
backend/formulas/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
backend/formulas/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
9
backend/formulas/models/__init__.py
Normal file
9
backend/formulas/models/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .formula import Formula
|
||||
from .symbol import Symbol
|
||||
from .category import FormulaCategory
|
||||
|
||||
__all__ = [
|
||||
"Formula",
|
||||
"Symbol",
|
||||
"FormulaCategory",
|
||||
]
|
||||
BIN
backend/formulas/models/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
backend/formulas/models/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/models/__pycache__/category.cpython-312.pyc
Normal file
BIN
backend/formulas/models/__pycache__/category.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/models/__pycache__/favorite.cpython-312.pyc
Normal file
BIN
backend/formulas/models/__pycache__/favorite.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/models/__pycache__/formula.cpython-312.pyc
Normal file
BIN
backend/formulas/models/__pycache__/formula.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
backend/formulas/models/__pycache__/symbol.cpython-312.pyc
Normal file
BIN
backend/formulas/models/__pycache__/symbol.cpython-312.pyc
Normal file
Binary file not shown.
12
backend/formulas/models/category.py
Normal file
12
backend/formulas/models/category.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.db import models
|
||||
|
||||
class FormulaCategory(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
prefix = models.PositiveIntegerField(unique=True) # cyfra `x` w kodzie xyz
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Kategoria wzoru"
|
||||
verbose_name_plural = "Kategorie wzorów"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.prefix} - {self.name}"
|
||||
17
backend/formulas/models/favorite.py
Normal file
17
backend/formulas/models/favorite.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# backend/formulas/models/favorite_formula.py
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from formulas.models.formula import Formula
|
||||
|
||||
class FavoriteFormula(models.Model):
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||
formula = models.ForeignKey(Formula, on_delete=models.CASCADE)
|
||||
added_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('user', 'formula')
|
||||
verbose_name = "Ulubiony wzór"
|
||||
verbose_name_plural = "Ulubione wzory"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username} ❤️ {self.formula.code}"
|
||||
38
backend/formulas/models/formula.py
Normal file
38
backend/formulas/models/formula.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from django.db import models
|
||||
from .category import FormulaCategory
|
||||
from users.models import User
|
||||
from django.utils import timezone
|
||||
from .symbol import Symbol
|
||||
|
||||
class Formula(models.Model):
|
||||
formula_id = models.CharField(max_length=100)
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.TextField(blank=True)
|
||||
meta = models.TextField(blank=True)
|
||||
category = models.ForeignKey(FormulaCategory, on_delete=models.PROTECT)
|
||||
tags = models.JSONField(default=list)
|
||||
latex = models.TextField()
|
||||
raw_latex = models.TextField()
|
||||
symbols = models.ManyToManyField(Symbol, related_name='formulas')
|
||||
calculator = models.CharField(max_length=100)
|
||||
revision = models.PositiveIntegerField(default=1)
|
||||
code = models.CharField(max_length=10, unique=True)
|
||||
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.code:
|
||||
base_prefix = f"{self.category.prefix:02d}"
|
||||
existing_codes = Formula.objects.filter(category=self.category).values_list('code', flat=True)
|
||||
index = 1
|
||||
while True:
|
||||
proposed_code = f"{base_prefix}{index:02d}{self.revision:02d}"
|
||||
if proposed_code not in existing_codes:
|
||||
self.code = proposed_code
|
||||
break
|
||||
index += 1
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} ({self.code})"
|
||||
25
backend/formulas/models/symbol.py
Normal file
25
backend/formulas/models/symbol.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from django.db import models
|
||||
from .category import FormulaCategory
|
||||
|
||||
class Symbol(models.Model):
|
||||
symbol_id = models.CharField(max_length=10) # np. F
|
||||
name = models.CharField(max_length=255)
|
||||
unit = models.CharField(max_length=50)
|
||||
description = models.TextField(blank=True)
|
||||
category = models.ForeignKey(FormulaCategory, on_delete=models.PROTECT)
|
||||
tags = models.JSONField(default=list, blank=True)
|
||||
revision = models.PositiveIntegerField(default=1)
|
||||
code = models.CharField(max_length=10, unique=True, editable=False)
|
||||
meta = models.TextField(blank=True) # np. meta-opis dla SEO / edytora
|
||||
|
||||
|
||||
#Zaspis zmiennej z code
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.code:
|
||||
count = Symbol.objects.filter(category=self.category).count() + 1
|
||||
self.code = f"{self.category.prefix:02d}{count:02d}{self.revision:02d}"
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
#Definiowanie czym jest "self"
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.symbol_id}) [{self.code}]"
|
||||
9
backend/formulas/permissions.py
Normal file
9
backend/formulas/permissions.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from rest_framework.permissions import BasePermission
|
||||
|
||||
class IsAdminOrEditor(BasePermission):
|
||||
def has_permission(self, request, view):
|
||||
return request.method in ("GET", "HEAD", "OPTIONS") or (
|
||||
request.user and request.user.is_authenticated and (
|
||||
request.user.is_superuser or getattr(request.user, "role", None) == "editor"
|
||||
)
|
||||
)
|
||||
9
backend/formulas/serializers/__init__.py
Normal file
9
backend/formulas/serializers/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from .formula import FormulaSerializer
|
||||
from .symbol import SymbolSerializer
|
||||
from .category import FormulaCategorySerializer
|
||||
|
||||
__all__ = [
|
||||
"FormulaSerializer",
|
||||
"SymbolSerializer",
|
||||
"FormulaCategorySerializer",
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
BIN
backend/formulas/serializers/__pycache__/formula.cpython-312.pyc
Normal file
BIN
backend/formulas/serializers/__pycache__/formula.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/serializers/__pycache__/symbol.cpython-312.pyc
Normal file
BIN
backend/formulas/serializers/__pycache__/symbol.cpython-312.pyc
Normal file
Binary file not shown.
7
backend/formulas/serializers/category.py
Normal file
7
backend/formulas/serializers/category.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
from formulas.models.category import FormulaCategory
|
||||
|
||||
class FormulaCategorySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = FormulaCategory
|
||||
fields = '__all__'
|
||||
8
backend/formulas/serializers/formula.py
Normal file
8
backend/formulas/serializers/formula.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from rest_framework import serializers
|
||||
from formulas.models.formula import Formula
|
||||
|
||||
class FormulaSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Formula
|
||||
fields = "__all__"
|
||||
read_only_fields = ('code', 'created_by', 'created_at')
|
||||
8
backend/formulas/serializers/symbol.py
Normal file
8
backend/formulas/serializers/symbol.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# backend/formulas/serializers/symbol.py
|
||||
from rest_framework import serializers
|
||||
from formulas.models.symbol import Symbol
|
||||
|
||||
class SymbolSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Symbol
|
||||
fields = "__all__"
|
||||
3
backend/formulas/tests.py
Normal file
3
backend/formulas/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
19
backend/formulas/urls.py
Normal file
19
backend/formulas/urls.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from .views import SymbolViewSet, FormulaViewSet, FormulaCategoryViewSet
|
||||
|
||||
# 🔧 Router z obsługą lookup_field='code'
|
||||
class LookupByCodeRouter(DefaultRouter):
|
||||
def get_lookup_regex(self, viewset, lookup_prefix=''):
|
||||
if hasattr(viewset, 'lookup_field') and viewset.lookup_field == 'code':
|
||||
return r'(?P<code>[^/.]+)'
|
||||
return super().get_lookup_regex(viewset, lookup_prefix)
|
||||
|
||||
router = LookupByCodeRouter()
|
||||
router.register(r'symbols', SymbolViewSet, basename='symbol')
|
||||
router.register(r'formulas', FormulaViewSet, basename='formula')
|
||||
router.register(r'formulascategories', FormulaCategoryViewSet, basename='category')
|
||||
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
]
|
||||
11
backend/formulas/views/__init__.py
Normal file
11
backend/formulas/views/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from .formula import FormulaViewSet
|
||||
from .symbol import SymbolViewSet
|
||||
from .category import FormulaCategoryViewSet
|
||||
from .favorite import FavoriteFormulaViewSet
|
||||
|
||||
__all__ = [
|
||||
"FormulaViewSet",
|
||||
"SymbolViewSet",
|
||||
"FormulaCategoryViewSet",
|
||||
"FavoriteFormulaViewSet",
|
||||
]
|
||||
BIN
backend/formulas/views/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
backend/formulas/views/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/views/__pycache__/category.cpython-312.pyc
Normal file
BIN
backend/formulas/views/__pycache__/category.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/views/__pycache__/favorite.cpython-312.pyc
Normal file
BIN
backend/formulas/views/__pycache__/favorite.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/views/__pycache__/formula.cpython-312.pyc
Normal file
BIN
backend/formulas/views/__pycache__/formula.cpython-312.pyc
Normal file
Binary file not shown.
BIN
backend/formulas/views/__pycache__/symbol.cpython-312.pyc
Normal file
BIN
backend/formulas/views/__pycache__/symbol.cpython-312.pyc
Normal file
Binary file not shown.
11
backend/formulas/views/category.py
Normal file
11
backend/formulas/views/category.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# backend/formulas/views/category.py
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from formulas.models.category import FormulaCategory
|
||||
from formulas.serializers.category import FormulaCategorySerializer
|
||||
from formulas.permissions import IsAdminOrEditor
|
||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
||||
|
||||
class FormulaCategoryViewSet(ModelViewSet):
|
||||
queryset = FormulaCategory.objects.all()
|
||||
serializer_class = FormulaCategorySerializer
|
||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||
BIN
backend/formulas/views/category.zip
Normal file
BIN
backend/formulas/views/category.zip
Normal file
Binary file not shown.
40
backend/formulas/views/favorite.py
Normal file
40
backend/formulas/views/favorite.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# backend/formulas/views/favorite.py
|
||||
from rest_framework import status, viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from formulas.models.formula import Formula
|
||||
from formulas.models.favorite import FavoriteFormula
|
||||
from formulas.serializers.formula import FormulaSerializer
|
||||
|
||||
class FavoriteFormulaViewSet(viewsets.ViewSet):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def list(self, request):
|
||||
favorites = FavoriteFormula.objects.filter(user=request.user)
|
||||
formulas = [fav.formula for fav in favorites]
|
||||
serializer = FormulaSerializer(formulas, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def add(self, request, pk=None):
|
||||
try:
|
||||
formula = Formula.objects.get(pk=pk)
|
||||
except Formula.DoesNotExist:
|
||||
return Response({"detail": "Formula not found."}, status=404)
|
||||
|
||||
fav, created = FavoriteFormula.objects.get_or_create(user=request.user, formula=formula)
|
||||
if not created:
|
||||
return Response({"detail": "Already in favorites."}, status=400)
|
||||
|
||||
return Response({"detail": "Added to favorites."}, status=200)
|
||||
|
||||
@action(detail=True, methods=['delete'])
|
||||
def remove(self, request, pk=None):
|
||||
try:
|
||||
fav = FavoriteFormula.objects.get(user=request.user, formula_id=pk)
|
||||
fav.delete()
|
||||
return Response({"detail": "Removed from favorites."}, status=204)
|
||||
except FavoriteFormula.DoesNotExist:
|
||||
return Response({"detail": "Not in favorites."}, status=404)
|
||||
21
backend/formulas/views/formula.py
Normal file
21
backend/formulas/views/formula.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# backend/formulas/views/formula.py
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from formulas.models.formula import Formula
|
||||
from formulas.serializers.formula import FormulaSerializer
|
||||
from formulas.permissions import IsAdminOrEditor
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from formulas.serializers import SymbolSerializer
|
||||
|
||||
class FormulaViewSet(ModelViewSet):
|
||||
queryset = Formula.objects.all()
|
||||
serializer_class = FormulaSerializer
|
||||
permission_classes = [IsAdminOrEditor]
|
||||
lookup_field = "code"
|
||||
|
||||
@action(detail=True, methods=['get'], url_path='symbols')
|
||||
def get_symbols(self, request, code=None):
|
||||
formula = self.get_object()
|
||||
symbols = formula.symbols.all()
|
||||
serializer = SymbolSerializer(symbols, many=True)
|
||||
return Response(serializer.data)
|
||||
10
backend/formulas/views/symbol.py
Normal file
10
backend/formulas/views/symbol.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from formulas.models.symbol import Symbol
|
||||
from formulas.serializers.symbol import SymbolSerializer
|
||||
from formulas.permissions import IsAdminOrEditor
|
||||
|
||||
class SymbolViewSet(ModelViewSet):
|
||||
queryset = Symbol.objects.all()
|
||||
serializer_class = SymbolSerializer
|
||||
permission_classes = [IsAdminOrEditor]
|
||||
lookup_field = "code"
|
||||
Reference in New Issue
Block a user