Commit 77cce1b1 authored by Florent Chehab's avatar Florent Chehab
Browse files

feat(backend): refactor/cleaned/ infer get_serializer

* Cleaned all init files
* Infer the serializer from the model instead of having it in the models
* Updated the doc accordingly
* Fixed typos

Fixes #93
Fixes #85
parent cb86531b
from django.core.validators import URLValidator
from rest_framework.validators import ValidationError
def validate_extension(allowed_extensions, string):
allowed_extensions = [
allowed_extension.lower() for allowed_extension in allowed_extensions
]
try:
if string.split(".")[-1].lower() not in allowed_extensions:
raise ValidationError(
"The file you submitted has an unauthorized extension"
)
except KeyError:
raise ValidationError("File extension not recognized")
def validate_url(config, string):
string = str(string)
validate = URLValidator(schemes=("http", "https", "ftp", "ftps"))
validate(string)
try:
validators = config["validators"]
for validator in validators:
validator_content = validators[validator]
if validator == "extension":
validate_extension(validator_content, string)
elif validator == "max_length":
if len(string) > validator_content:
raise ValidationError("Your url is too long !")
else:
raise Exception("Dev, you have implement something here...")
except KeyError:
pass
from .checks import check_required
from .url import validate_url
from .text import validate_text
from rest_framework.validators import ValidationError
from .tags_config import PHOTOS_TAG_CONFIG
from .tags_config import USEFULL_LINKS_CONFIG
from django.core.validators import URLValidator
from rest_framework.exceptions import ValidationError
from backend_app.validators.tags_config.photos import PHOTOS_TAG_CONFIG
from backend_app.validators.tags_config.useful_links import USEFULL_LINKS_CONFIG
def missing_field(field):
return ValidationError("{} : this field is required".format(field))
def check_required(config, content):
for field in config:
if config[field]["required"]:
try:
val = content[field]
if type(val) is str:
if len(val) == 0:
raise missing_field(field)
if val is None:
raise missing_field(field)
except KeyError:
raise missing_field(field)
def tagged_item_validation(attrs):
tag_config = attrs["tag"].config
try:
sumbitted_content = attrs["custom_content"]
submitted_content = attrs["custom_content"]
except KeyError:
assert len(tag_config.keys()) == 0
return True
validate_content_against_config(tag_config, sumbitted_content)
validate_content_against_config(tag_config, submitted_content)
def validate_content_against_config(config, content):
......@@ -49,3 +66,52 @@ def validate_content_against_config(config, content):
validate_content_against_config(field_config["content"], item)
else:
raise Exception("Dev, you have implement something here...")
def validate_text(config, string):
string = str(string) # might cause error with number ?
try:
validators = config["validators"]
for validator in validators:
validator_content = validators[validator]
if validator == "max_length":
if len(string) > validator_content:
raise ValidationError("Your text is too long !")
else:
raise Exception("Dev, you have implement something here...")
except KeyError:
pass
def validate_extension(allowed_extensions, string):
allowed_extensions = [
allowed_extension.lower() for allowed_extension in allowed_extensions
]
try:
if string.split(".")[-1].lower() not in allowed_extensions:
raise ValidationError(
"The file you submitted has an unauthorized extension"
)
except KeyError:
raise ValidationError("File extension not recognized")
def validate_url(config, string):
string = str(string)
validate = URLValidator(schemes=("http", "https", "ftp", "ftps"))
validate(string)
try:
validators = config["validators"]
for validator in validators:
validator_content = validators[validator]
if validator == "extension":
validate_extension(validator_content, string)
elif validator == "max_length":
if len(string) > validator_content:
raise ValidationError("Your url is too long !")
else:
raise Exception("Dev, you have implement something here...")
except KeyError:
pass
......@@ -9,8 +9,4 @@ CAS_SERVER_URL = "https://cas.utc.fr/cas/"
# We want to map the attribute returned by the cas to the user model attribute
CAS_APPLY_ATTRIBUTES_TO_USER = True
# Mapping of the attribute
CAS_RENAME_ATTRIBUTES = {
"mail": "email",
"givenName": "first_name",
"sn": "last_name",
}
CAS_RENAME_ATTRIBUTES = {"mail": "email", "givenName": "first_name", "sn": "last_name"}
......@@ -45,20 +45,6 @@ Here is the UML of their inheritance:
![abstract](../../generated/abstract.svg)
?> :warning: what is said below will soon be unnecessary: https://gitlab.utc.fr/rex-dri/rex-dri/issues/85
!> Models that inherit from `VersionedEssentialModule` (and therefore `Module`) must have the following calls method:
```python
class MyAwesomeModel(VersionedEssentialModule):
@classmethod
def get_serializer(cls):
return MyAwesomeModelSerializer
...
```
This method is used in the `VersionSerializer` class to convert version data back to a model instance.
#### General idea
So to define a model for the app, you should (in most cases) use one of the three base classes defined above. What remains is to define a model just like you would do for any Django Model. Here is an example (you have tons of them in app already):
......@@ -204,4 +190,14 @@ class EssentialModuleViewSet(BaseModelViewSet):
:information_desk_person: Sometimes it will be useful to have different viewsets for the same serializer, for instance if you want an api endpoint that returns the data filtered in a certain way.
!> You should avoid having multiple serializers for the same model since it may brake things related to deserializing previous versions of models.
!> You should avoid having multiple serializers for the same model, especially if that model is versioned.
In fact, to deserialize the versions, we try to infer the correct serializer to use in `backend/backend_app/models/version.py`. In case multiple serializers point to same model, you must define the `get_serializer` class method in your model:
```python
class MyAwesomeModel(VersionedEssentialModule):
@classmethod
def get_serializer(cls):
return MyAwesomeModelSerializer
...
```
......@@ -12,7 +12,7 @@ make django_shell
And by running:
```python
from backend_app.load_data import load_all
from backend_app.load_data.load_all import load_all
load_all()
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment