first commit
This commit is contained in:
0
api/__init__.py
Normal file
0
api/__init__.py
Normal file
3
api/admin.py
Normal file
3
api/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
api/apps.py
Normal file
6
api/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'api'
|
||||
34
api/migrations/0001_initial.py
Normal file
34
api/migrations/0001_initial.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Generated by Django 5.2.4 on 2025-07-12 12:37
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Collection',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=64)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='VisualAsset',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=128)),
|
||||
('image', models.ImageField(upload_to='cards/')),
|
||||
('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.collection')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['name'],
|
||||
},
|
||||
),
|
||||
]
|
||||
29
api/migrations/0002_card_delete_visualasset.py
Normal file
29
api/migrations/0002_card_delete_visualasset.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.2.4 on 2025-07-13 11:17
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Card',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=128)),
|
||||
('image', models.ImageField(upload_to='cards/')),
|
||||
('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cards', related_query_name='card', to='api.collection')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['name'],
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='VisualAsset',
|
||||
),
|
||||
]
|
||||
0
api/migrations/__init__.py
Normal file
0
api/migrations/__init__.py
Normal file
19
api/models.py
Normal file
19
api/models.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Collection(models.Model):
|
||||
name = models.CharField(max_length=64)
|
||||
|
||||
|
||||
class Card(models.Model):
|
||||
name = models.CharField(max_length=128)
|
||||
collection = models.ForeignKey(
|
||||
Collection,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="cards",
|
||||
related_query_name="card",
|
||||
)
|
||||
image = models.ImageField(upload_to="cards/")
|
||||
|
||||
class Meta:
|
||||
ordering = ["name"]
|
||||
42
api/serializers.py
Normal file
42
api/serializers.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from rest_framework import serializers
|
||||
from api.models import Card, Collection
|
||||
|
||||
|
||||
class CardSerializer(serializers.ModelSerializer):
|
||||
image_url = serializers.SerializerMethodField()
|
||||
collection_name = serializers.CharField(write_only=True, required=False)
|
||||
collection = serializers.PrimaryKeyRelatedField(
|
||||
queryset=Collection.objects.all(), required=False
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Card
|
||||
fields = ["id", "name", "collection", "collection_name", "image", "image_url"]
|
||||
|
||||
def create(self, validated_data):
|
||||
collection_name = validated_data.pop("collection_name", None)
|
||||
if collection_name:
|
||||
collection, _ = Collection.objects.get_or_create(name=collection_name)
|
||||
validated_data["collection"] = collection
|
||||
elif not validated_data.get("collection"):
|
||||
raise serializers.ValidationError(
|
||||
{
|
||||
"collection": "This field is required if collection_name is not provided."
|
||||
}
|
||||
)
|
||||
return super().create(validated_data)
|
||||
|
||||
def get_image_url(self, obj):
|
||||
request = self.context.get("request")
|
||||
if obj.image:
|
||||
url = obj.image.url
|
||||
if request is not None:
|
||||
return request.build_absolute_uri(url)
|
||||
return url
|
||||
return None
|
||||
|
||||
|
||||
class CollectionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Collection
|
||||
fields = ["id", "name"]
|
||||
3
api/tests.py
Normal file
3
api/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
16
api/views.py
Normal file
16
api/views.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from rest_framework import viewsets
|
||||
from api.models import Card, Collection
|
||||
from api.serializers import CardSerializer, CollectionSerializer
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
|
||||
|
||||
class CardViewSet(viewsets.ModelViewSet):
|
||||
queryset = Card.objects.all()
|
||||
serializer_class = CardSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = ["collection__name"]
|
||||
|
||||
|
||||
class CollectionViewSet(viewsets.ModelViewSet):
|
||||
queryset = Collection.objects.all()
|
||||
serializer_class = CollectionSerializer
|
||||
Reference in New Issue
Block a user