diff --git a/backend/apps/quib/__init__.py b/backend/apps/quib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/quib/admin.py b/backend/apps/quib/admin.py new file mode 100644 index 00000000..ce4f108a --- /dev/null +++ b/backend/apps/quib/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin + +from .models import Quib + + +@admin.register(Quib) +class QuibAdmin(admin.ModelAdmin): + list_display = ('title', 'quiblet', 'quibber', 'is_public', 'created_at') + search_fields = ('title', 'quiblet__name', 'quibber__name') diff --git a/backend/apps/quib/apps.py b/backend/apps/quib/apps.py new file mode 100644 index 00000000..fb862e68 --- /dev/null +++ b/backend/apps/quib/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class QuibConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.quib' diff --git a/backend/apps/quib/migrations/0001_initial.py b/backend/apps/quib/migrations/0001_initial.py new file mode 100644 index 00000000..59a59197 --- /dev/null +++ b/backend/apps/quib/migrations/0001_initial.py @@ -0,0 +1,90 @@ +# Generated by Django 5.1.3 on 2024-12-07 04:12 + +import django.db.models.deletion +import shortuuid.django_fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('quiblet', '0003_delete_quib'), + ('user', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Quib', + fields=[ + ( + 'created_at', + models.DateTimeField(auto_now_add=True, verbose_name='create at'), + ), + ('is_public', models.BooleanField(default=True, verbose_name='is public')), + ( + 'id', + shortuuid.django_fields.ShortUUIDField( + alphabet='abcdefghijklmnopqrstuvwxyz0123456789', + editable=False, + length=7, + max_length=7, + prefix='', + primary_key=True, + serialize=False, + verbose_name='id', + ), + ), + ('title', models.CharField(max_length=255, verbose_name='title')), + ( + 'slug', + models.SlugField( + blank=True, editable=False, max_length=25, verbose_name='slug' + ), + ), + ('content', models.TextField(verbose_name='content')), + ( + 'dislikes', + models.ManyToManyField( + blank=True, + related_name='disliked_quibs', + to='user.profile', + verbose_name='dislikes', + ), + ), + ( + 'likes', + models.ManyToManyField( + blank=True, + related_name='liked_quibs', + to='user.profile', + verbose_name='likes', + ), + ), + ( + 'quibber', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='quibs', + to='user.profile', + verbose_name='quibber', + ), + ), + ( + 'quiblet', + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name='quibs', + to='quiblet.quiblet', + verbose_name='quiblet', + ), + ), + ], + options={ + 'verbose_name': 'Quib', + 'verbose_name_plural': 'Quibs', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/backend/apps/quib/migrations/__init__.py b/backend/apps/quib/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/apps/quib/models.py b/backend/apps/quib/models.py new file mode 100644 index 00000000..07924f15 --- /dev/null +++ b/backend/apps/quib/models.py @@ -0,0 +1,46 @@ +from django.db import models +from django.utils.text import slugify +from django.utils.translation import gettext_lazy as _ + +from apps.quiblet.models import Quiblet +from apps.user.models import Profile +from common.mixins import CreatedAtMixin, IsPublicMixin, ShortUUIDIdMixin + + +class Quib(CreatedAtMixin, IsPublicMixin, ShortUUIDIdMixin): + quiblet = models.ForeignKey( + Quiblet, + related_name='quibs', + verbose_name=_('quiblet'), + on_delete=models.CASCADE, + ) + quibber = models.ForeignKey( + Profile, + related_name='quibs', + verbose_name=_('quibber'), + on_delete=models.CASCADE, + ) + title = models.CharField(_('title'), max_length=255) + slug = models.SlugField(_('slug'), editable=False, max_length=25, blank=True) + content = models.TextField(_('content')) + likes = models.ManyToManyField( + Profile, related_name='liked_quibs', blank=True, verbose_name=_('likes') + ) + dislikes = models.ManyToManyField( + Profile, related_name='disliked_quibs', blank=True, verbose_name=_('dislikes') + ) + + def save(self, *args, **kwargs): + """Override save method to slugify title.""" + if not self.slug: + self.slug = slugify(self.title[:25]) + + super(Quib, self).save(*args, **kwargs) + + def __str__(self): + return f'{self.pk}/{self.slug}' + + class Meta: # type: ignore + verbose_name = 'Quib' + verbose_name_plural = 'Quibs' + ordering = ['-created_at'] diff --git a/backend/apps/quiblet/admin.py b/backend/apps/quiblet/admin.py index 4c0ef67c..3d767a4f 100644 --- a/backend/apps/quiblet/admin.py +++ b/backend/apps/quiblet/admin.py @@ -1,15 +1,9 @@ from django.contrib import admin -from .models import Quib, Quiblet +from .models import Quiblet @admin.register(Quiblet) class QuibletAdmin(admin.ModelAdmin): list_display = ('name', 'is_public', 'created_at') search_fields = ('name',) - - -@admin.register(Quib) -class QuibAdmin(admin.ModelAdmin): - list_display = ('title', 'quiblet', 'quibber', 'is_public', 'created_at') - search_fields = ('title', 'quiblet__name', 'quibber__name') diff --git a/backend/apps/quiblet/migrations/0003_delete_quib.py b/backend/apps/quiblet/migrations/0003_delete_quib.py new file mode 100644 index 00000000..30751f1d --- /dev/null +++ b/backend/apps/quiblet/migrations/0003_delete_quib.py @@ -0,0 +1,16 @@ +# Generated by Django 5.1.3 on 2024-12-07 04:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('quiblet', '0002_initial'), + ] + + operations = [ + migrations.DeleteModel( + name='Quib', + ), + ] diff --git a/backend/apps/quiblet/models.py b/backend/apps/quiblet/models.py index 37b25626..ab173590 100644 --- a/backend/apps/quiblet/models.py +++ b/backend/apps/quiblet/models.py @@ -35,42 +35,3 @@ class Meta: # type: ignore def __str__(self): return f'q/{self.name}' - - -class Quib(CreatedAtMixin, IsPublicMixin, ShortUUIDIdMixin): - quiblet = models.ForeignKey( - Quiblet, - related_name='quibs', - verbose_name=_('quiblet'), - on_delete=models.CASCADE, - ) - quibber = models.ForeignKey( - Profile, - related_name='quibs', - verbose_name=_('quibber'), - on_delete=models.CASCADE, - ) - title = models.CharField(_('title'), max_length=255) - slug = models.SlugField(_('slug'), editable=False, max_length=25, blank=True) - content = models.TextField(_('content')) - likes = models.ManyToManyField( - Profile, related_name='liked_quibs', blank=True, verbose_name=_('likes') - ) - dislikes = models.ManyToManyField( - Profile, related_name='disliked_quibs', blank=True, verbose_name=_('dislikes') - ) - - def save(self, *args, **kwargs): - """Override save method to slugify title.""" - if not self.slug: - self.slug = slugify(self.title[:25]) - - super(Quib, self).save(*args, **kwargs) - - def __str__(self): - return f'{self.pk}/{self.slug}' - - class Meta: # type: ignore - verbose_name = 'Quib' - verbose_name_plural = 'Quibs' - ordering = ['-created_at'] diff --git a/backend/config/settings.py b/backend/config/settings.py index 8749a1d3..c10737b2 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -28,17 +28,16 @@ # Application definition -INSTALLED_APPS = [ - # auth related app on top - 'apps.user', - # django middlewares +DEFAULT_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - # django extensions +] + +THIRD_PARTY_APPS = [ 'django_extensions', # rest framework 'rest_framework', @@ -52,12 +51,18 @@ # openapi 'drf_spectacular', 'drf_spectacular_sidecar', - # apps - 'apps.quiblet', - # file middleware (should be at last) + # file middleware 'django_cleanup', ] +SELF_APPS = [ + 'apps.user', + 'apps.quiblet', + 'apps.quib', +] + +INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + SELF_APPS + REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'apps.user.auth.ExtendedTokenAuthentication',