Skip to content

Commit

Permalink
feat: daily article bulk import from admin
Browse files Browse the repository at this point in the history
  • Loading branch information
julienc91 committed Oct 27, 2024
1 parent 17cdc08 commit 8a6663d
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
65 changes: 64 additions & 1 deletion backend/caviardeul/admin/article.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
from datetime import timedelta

from django.contrib import admin
from django.core.exceptions import ValidationError
from import_export.admin import ImportMixin
from import_export.fields import Field
from import_export.resources import ModelResource
from import_export.widgets import BooleanWidget

from caviardeul.models import CustomArticle, DailyArticle

Expand All @@ -20,8 +27,64 @@ class CustomArticleAdmin(admin.ModelAdmin):
ordering = ("-created_at",)


class DailyArticleResource(ModelResource):
_page_ids: set[str]
_page_names: set[str]
_last_article: DailyArticle
confirm_discrepancy = Field(widget=BooleanWidget(), default=False)

class Meta:
model = DailyArticle
fields = ("page_id", "page_name", "confirm_discrepancy")
use_bulk = True
force_init_instance = True

def before_import(self, dataset, **kwargs):
super().before_import(dataset, **kwargs)

articles = DailyArticle.objects.only("page_id", "page_name")
self._page_ids = {article.page_id.lower() for article in articles}
self._page_names = {article.page_name.lower() for article in articles}
self._last_article = DailyArticle.objects.order_by("-id").first()

def before_import_row(self, row, **kwargs):
super().before_import_row(row, **kwargs)
page_id = row["page_id"].lower()
page_name = row["page_name"].lower()
confirm = BooleanWidget().clean(row["confirm_discrepancy"]) or False

if " " in page_id:
raise ValidationError({"page_id": "Invalid character"})
if "_" in page_name:
raise ValidationError({"page_name": "Invalid character"})
if page_id in self._page_ids:
raise ValidationError({"page_id": "Duplicate entry"})
if page_name in self._page_names:
raise ValidationError({"page_name": "Duplicate entry"})
if (page_id.replace("_", " ") == page_name) and confirm:
raise ValidationError({"confirm_discrepancy": "Unexpected confirmation"})
if (page_id.replace("_", " ") != page_name) and not confirm:
raise ValidationError({"confirm_discrepancy": "Confirm discrepancy"})

self._page_ids.add(page_id)
self._page_names.add(page_name)

def before_save_instance(self, instance, row, **kwargs):
super().before_save_instance(instance, row, **kwargs)
instance.id = self._last_article.id + 1
instance.date = self._last_article.date + timedelta(days=1)
instance.median = 0
instance.stats = {}
instance.nb_winners = 0
instance.nb_daily_winners = 0

self._last_article = instance


@admin.register(DailyArticle)
class DailyArticleAdmin(admin.ModelAdmin):
class DailyArticleAdmin(ImportMixin, admin.ModelAdmin):
list_display = ["id", "page_name", "date", "nb_daily_winners"]
search_fields = ("page_id", "page_name")
ordering = ("-id",)

resource_class = DailyArticleResource
3 changes: 3 additions & 0 deletions backend/caviardeul/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"import_export",
"corsheaders",
"caviardeul",
]
Expand Down Expand Up @@ -147,6 +148,8 @@
},
]

IMPORT_EXPORT_TMP_STORAGE_CLASS = "import_export.tmp_storages.CacheStorage"

AUTH_USER_MODEL = "caviardeul.User"

# Internationalization
Expand Down
1 change: 1 addition & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies = [
"redis ~= 5.0.7",
"pydantic ~= 2.9.0",
"sentry-sdk[django]",
"django-import-export>=4.2.0",
]

[project.optional-dependencies]
Expand Down
34 changes: 34 additions & 0 deletions backend/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8a6663d

Please sign in to comment.