pip install djkit
from djkit.utils import Obfuscator Obfuscator.email("abcdqweqwe@test.com") # abcdq****@test.com' Obfuscator.obfuscate('my_super_confidential_secret') # 'my_super_confidential_s*****'# models.py from django.db import models class Human(models.Model): class Level(models.IntegerChoices): BEGINNER = 0 INTERMEDIATE = 1 ADVANCED = 2 class MilitaryStatus(models.TextChoices): EXEMPTED = "exempted", "Exempted" SERVED = "served", "Served" POSTPONED = "postponed", "Postponed" name = models.CharField(max_length=128) level = models.IntegerField(choices=Level.choices) military_status = models.CharField( choices=MilitaryStatus.choices, max_length=128 )# serializers.py from rest_framework import serializers from djkit.rest_framework.serializers import EnumSerializer from example.core import models class HumanSerializer(serializers.ModelSerializer): level = EnumSerializer(enum=models.Human.Level) military_status = EnumSerializer(enum=models.Human.MilitaryStatus) class Meta: model = models.Human fields = [ 'id', 'level', 'military_status', ]# wherever.py from example.core.serializers import HumanSerializer from example.core.models import Human human = Human.objects.find(id=1) serializer = HumanSerializer(human) # level = BEGINNER, military_status = EXEMPTED# wherever.py from example.core.serializers import HumanSerializer data = { "level": "BEGINNER", "MILITARY_STATUS": "EXEMPTED", } instance = HumanSerializer(data=data) instance.is_valid() instance.save()- Assuming Pandas
import pandas as pd from djkit.rest_framework.pandas import TableUploadField # or PandasTableUploadField from rest_framework import serializers class MySerializer(serializers.ModelSerializer): file = TableUploadField() def create(self, validated_data): file: pd.DataFrame = validated_data['file'] # do logic, don't do row based validation here return validated_data # optional method def validate_file_row(self, row, index, table_df): if row.iloc[0] == "X": row.iloc[0] = "Y" # return new row, or None and changes won't be reflected return row- Assuming Pola.rs
import polars as pl from djkit.rest_framework.polars import TableUploadField # or PolarsTableUploadField from rest_framework import serializers class MySerializer(serializers.ModelSerializer): file = TableUploadField() def create(self, validated_data): file: pl.DataFrame = validated_data['file'] # do logic, don't do row based validation here return validated_data # optional method def validate_file_row(self, row, index, table_df): # do polars logic, return new row or None return rowTableUploadFieldiswrite_only- TableUploadField is easily extended, use your own library if you want
from djkit.rest_framework.serializers import TableUploadField as BaseTableUploadField def read_csv(source): return ... def read_excel(source): return ... class TableUploadField(BaseTableUploadField): handlers = { "csv": read_csv, "xlsx": read_excel, "xls": read_excel, "xlsm": read_excel, "xlsb": read_excel, "odf": read_excel, "ods": read_excel, "odt": read_excel, } def update_row(self, table_object: "YourLibraryDataFrame", index, new_row): """how your library updates the row""" can_parse_csv = "csv" in field.allowed_upload_formatscan_parse_csv = field.is_allowed_format('obj') # Falsefrom djkit.rest_framework.pandas import PandasTableUploadField import pandas as pd class Serializer(...): pandas_file = PandasTableUploadField(handler_kwargs={ # by format "xlsx": { # args for read_excel would be here "engine": "openpyxl" }, # or by reference pd.read_csv: { "delimiter": "\t" } })-
The same logic applies to all
TableUploadFieldsubclasses. -
djkit provides easily methods for overriding most of the logic.
-
If you want a field that does aggregation or something, override
process_tableonTableUploadField
from djkit.rest_framework.serializers import ObfuscatedCharField, ObfuscatedEmailField, ObfuscatedFieldMixin class MySerializer(...): email = ObfuscatedEmailField() # in the API, it's obfuscated name = ObfuscatedCharField() # same applies here class MyCustomObfuscatedApiKeyField(ObfuscatedFieldMixin, MyApiKeyField): passREST_FRAMEWORK = { "DEFAULT_RENDERER_CLASSES": [ "djkit.rest_framework.renderers.JSONRenderer" ] }This will change you response schema in case of errors to
response = { "field_errors": [], "non_field_errors": [] }To run the project locally
pip install poetrypoetry installpoetry shellpre-commit install
To build the docs
make html
To run the tests
pytest .