Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rex Dri
Rex Dri
Commits
7266140c
Commit
7266140c
authored
Feb 24, 2019
by
Florent Chehab
Browse files
Merge branch 'cleaning' into 'master'
Cleaning See merge request
!50
parents
0e42118e
4fe1bdf2
Pipeline
#35396
passed with stages
in 4 minutes and 15 seconds
Changes
106
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
backend/backend_app/models/abstract/my_model/myModelSerializer.py
View file @
7266140c
from
django.contrib.contenttypes.models
import
ContentType
from
django.utils
import
timezone
from
backend_app.custom
import
MySerializerWithJSON
from
backend_app.permissions
import
is_moderation_required
from
backend_app.utils
import
get_user_level
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework.validators
import
ValidationError
from
rest_framework.validators
import
ValidationError
from
django.utils
import
timezone
from
.pendingModeration
import
PendingModeration
from
django.contrib.contenttypes.models
import
ContentType
from
.myModel
import
MyModel
from
.myModel
import
MyModel
from
.pendingModeration
import
PendingModerationSerializer
from
.pendingModeration
import
PendingModeration
,
PendingModerationSerializer
from
backend_app.utils
import
get_user_level
from
backend_app.permissions
import
is_moderation_required
from
backend_app.custom
import
MySerializerWithJSON
CLEANED_MY_MODEL_DATA
=
{
CLEANED_MY_MODEL_DATA
=
{
"moderated_by"
:
None
,
"moderated_by"
:
None
,
...
@@ -17,7 +18,10 @@ CLEANED_MY_MODEL_DATA = {
...
@@ -17,7 +18,10 @@ CLEANED_MY_MODEL_DATA = {
}
}
def
override_data
(
old_data
,
new_data
):
def
override_data
(
old_data
:
dict
,
new_data
:
dict
)
->
dict
:
"""Update the data in old_data with the one in new_data
"""
for
key
in
new_data
:
for
key
in
new_data
:
if
key
in
old_data
:
if
key
in
old_data
:
old_data
[
key
]
=
new_data
[
key
]
old_data
[
key
]
=
new_data
[
key
]
...
@@ -25,10 +29,20 @@ def override_data(old_data, new_data):
...
@@ -25,10 +29,20 @@ def override_data(old_data, new_data):
class
MyModelSerializer
(
MySerializerWithJSON
):
class
MyModelSerializer
(
MySerializerWithJSON
):
moderated_on
=
serializers
.
DateTimeField
(
format
=
"%Y-%m-%d %H:%M:%S"
,
read_only
=
True
)
"""Serializer to go along the MyModel Model. This serializer handles backend data moderation checks and tricks.
Raises:
ValidationError -- If you are trying to moderate something you don't have rights to
"""
######
# Basic fields serializers
updated_by
=
serializers
.
CharField
(
read_only
=
True
)
updated_on
=
serializers
.
DateTimeField
(
format
=
"%Y-%m-%d %H:%M:%S"
,
read_only
=
True
)
updated_on
=
serializers
.
DateTimeField
(
format
=
"%Y-%m-%d %H:%M:%S"
,
read_only
=
True
)
moderated_by
=
serializers
.
CharField
(
read_only
=
True
)
moderated_by
=
serializers
.
CharField
(
read_only
=
True
)
updated_by
=
serializers
.
CharField
(
read_only
=
True
)
moderated_on
=
serializers
.
DateTimeField
(
format
=
"%Y-%m-%d %H:%M:%S"
,
read_only
=
True
)
pending_moderation
=
serializers
.
SerializerMethodField
()
pending_moderation
=
serializers
.
SerializerMethodField
()
model_config
=
serializers
.
SerializerMethodField
()
model_config
=
serializers
.
SerializerMethodField
()
...
@@ -36,12 +50,24 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -36,12 +50,24 @@ class MyModelSerializer(MySerializerWithJSON):
# this is useful when a model has a dedicated primary key
# this is useful when a model has a dedicated primary key
id
=
serializers
.
SerializerMethodField
()
id
=
serializers
.
SerializerMethodField
()
def
get_model_config
(
self
,
obj
=
None
):
def
get_model_config
(
self
,
obj
=
None
)
->
dict
:
"""
Serializer for the `model_config` field.
`obj` is required in the function definition, but it's not used.
"""
return
self
.
Meta
.
model
.
model_config
return
self
.
Meta
.
model
.
model_config
# Optimization
# Class attribute to force the pending moderation to return the pending moderation data
# Or versionned element to return the number of versions
FORCE_FULL_DISPLAY
=
False
FORCE_FULL_DISPLAY
=
False
def
get_pending_moderation
(
self
,
obj
):
def
get_pending_moderation
(
self
,
obj
:
MyModel
):
"""
Serializer for the `pending_moderation` field
"""
# Optimization, in list mode, fetching all the pending moderation information is not optimal at all
if
not
self
.
FORCE_FULL_DISPLAY
and
self
.
context
[
"view"
].
action
==
"list"
:
if
not
self
.
FORCE_FULL_DISPLAY
and
self
.
context
[
"view"
].
action
==
"list"
:
return
None
return
None
else
:
else
:
...
@@ -53,19 +79,28 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -53,19 +79,28 @@ class MyModelSerializer(MySerializerWithJSON):
pending
,
many
=
True
,
read_only
=
True
,
context
=
self
.
context
pending
,
many
=
True
,
read_only
=
True
,
context
=
self
.
context
).
data
).
data
def
get_id
(
self
,
obj
):
def
get_id
(
self
,
obj
:
MyModel
):
"""
Serializer for the id field.
"""
return
obj
.
pk
return
obj
.
pk
class
Meta
:
class
Meta
:
model
=
MyModel
model
=
MyModel
def
my_validate
(
self
,
attrs
):
def
my_validate
(
self
,
attrs
):
"""
Function to be redefined in the subclasses to validate class fields.
"""
return
attrs
return
attrs
def
validate
(
self
,
attrs
):
def
validate
(
self
,
attrs
):
"""
"""
Validate `MyModel` fields and enforce certain field at the backend level.
TODO unit test this
TODO unit test this
"""
"""
# Enforce fields values based on request
self
.
user
=
self
.
context
[
"request"
].
user
self
.
user
=
self
.
context
[
"request"
].
user
self
.
user_level
=
get_user_level
(
self
.
user
)
self
.
user_level
=
get_user_level
(
self
.
user
)
...
@@ -80,6 +115,10 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -80,6 +115,10 @@ class MyModelSerializer(MySerializerWithJSON):
return
self
.
my_validate
(
attrs
)
return
self
.
my_validate
(
attrs
)
def
set_model_attr_no_moder
(
self
,
moderated_and_updated
):
def
set_model_attr_no_moder
(
self
,
moderated_and_updated
):
"""
TODO
TODO: rename ?
"""
now
=
timezone
.
now
()
now
=
timezone
.
now
()
self
.
override_validated_data
({
"moderated_by"
:
self
.
user
,
"moderated_on"
:
now
})
self
.
override_validated_data
({
"moderated_by"
:
self
.
user
,
"moderated_on"
:
now
})
...
@@ -87,9 +126,12 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -87,9 +126,12 @@ class MyModelSerializer(MySerializerWithJSON):
self
.
override_validated_data
({
"updated_by"
:
self
.
user
,
"updated_on"
:
now
})
self
.
override_validated_data
({
"updated_by"
:
self
.
user
,
"updated_on"
:
now
})
def
clean_validated_data
(
self
):
def
clean_validated_data
(
self
):
"""
Clear fields related to update and moderation
"""
self
.
override_validated_data
(
CLEANED_MY_MODEL_DATA
)
self
.
override_validated_data
(
CLEANED_MY_MODEL_DATA
)
def
override_validated_data
(
self
,
new_data
):
def
override_validated_data
(
self
,
new_data
:
dict
):
"""
"""
Method used to force specific attributes when saving a model
Method used to force specific attributes when saving a model
"""
"""
...
@@ -97,12 +139,23 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -97,12 +139,23 @@ class MyModelSerializer(MySerializerWithJSON):
self
.
validated_data
[
key
]
=
new_data
[
key
]
self
.
validated_data
[
key
]
=
new_data
[
key
]
def
my_pre_save
(
self
):
def
my_pre_save
(
self
):
"""
TODO, Analyse if usefull
"""
pass
pass
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
"""
TODO analyse, usefull ?
"""
return
self
.
my_save
(
*
args
,
**
kwargs
)
return
self
.
my_save
(
*
args
,
**
kwargs
)
def
my_save
(
self
,
*
args
,
**
kwargs
):
def
my_save
(
self
,
*
args
,
**
kwargs
):
"""
Function that handles all the moderation in a smart way.
Nothing has to be done to tell that we won't the data to be moderated, it is detected automatically.
"""
self
.
clean_validated_data
()
self
.
clean_validated_data
()
self
.
my_pre_save
()
self
.
my_pre_save
()
ct
=
ContentType
.
objects
.
get_for_model
(
self
.
Meta
.
model
)
ct
=
ContentType
.
objects
.
get_for_model
(
self
.
Meta
.
model
)
...
@@ -113,7 +166,7 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -113,7 +166,7 @@ class MyModelSerializer(MySerializerWithJSON):
if
self
.
instance
is
None
:
# we need to create the main model
if
self
.
instance
is
None
:
# we need to create the main model
# Store the user for squashing data in versions models
# Store the user for squashing data in versions models
self
.
validated_data
.
updated_by
=
self
.
user
self
.
validated_data
.
updated_by
=
self
.
user
self
.
instance
=
super
(
MyModelSerializer
,
self
).
save
(
*
args
,
**
kwargs
)
self
.
instance
=
super
().
save
(
*
args
,
**
kwargs
)
data_to_save
=
dict
()
data_to_save
=
dict
()
for
key
in
self
.
validated_data
:
for
key
in
self
.
validated_data
:
...
@@ -126,6 +179,7 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -126,6 +179,7 @@ class MyModelSerializer(MySerializerWithJSON):
data_to_save
=
override_data
(
data_to_save
,
CLEANED_MY_MODEL_DATA
)
data_to_save
=
override_data
(
data_to_save
,
CLEANED_MY_MODEL_DATA
)
# Save instance into pending moderation state
PendingModeration
.
objects
.
update_or_create
(
PendingModeration
.
objects
.
update_or_create
(
content_type
=
ct
,
content_type
=
ct
,
object_id
=
self
.
instance
.
pk
,
object_id
=
self
.
instance
.
pk
,
...
@@ -137,18 +191,18 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -137,18 +191,18 @@ class MyModelSerializer(MySerializerWithJSON):
)
)
return
self
.
instance
return
self
.
instance
else
:
else
:
# Moderation is not needed, we need to check whether it's a moderation or an update with no moderation
moderated_and_updated
=
True
moderated_and_updated
=
True
if
self
.
instance
is
None
:
if
self
.
instance
is
None
:
self
.
set_model_attr_no_moder
(
moderated_and_updated
)
self
.
set_model_attr_no_moder
(
moderated_and_updated
)
return
super
(
MyModelSerializer
,
self
).
save
(
*
args
,
**
kwargs
)
return
super
().
save
(
*
args
,
**
kwargs
)
else
:
else
:
try
:
try
:
pending_instance
=
PendingModeration
.
objects
.
get
(
pending_instance
=
PendingModeration
.
objects
.
get
(
content_type
=
ct
,
object_id
=
self
.
instance
.
pk
content_type
=
ct
,
object_id
=
self
.
instance
.
pk
)
)
self
.
clean_validated_data
()
# Make that it is done...
self
.
clean_validated_data
()
# Make
quez
that it is done...
# We have to compare the serialized data
# We have to compare the serialized data
# So we make sure to compare the same elements
# So we make sure to compare the same elements
key_to_remove
=
[]
key_to_remove
=
[]
...
@@ -157,6 +211,7 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -157,6 +211,7 @@ class MyModelSerializer(MySerializerWithJSON):
key_to_remove
.
append
(
key
)
key_to_remove
.
append
(
key
)
for
key
in
key_to_remove
:
for
key
in
key_to_remove
:
self
.
initial_data
.
pop
(
key
,
None
)
self
.
initial_data
.
pop
(
key
,
None
)
if
pending_instance
.
new_object
==
self
.
initial_data
:
if
pending_instance
.
new_object
==
self
.
initial_data
:
moderated_and_updated
=
False
moderated_and_updated
=
False
self
.
validated_data
[
"updated_by"
]
=
pending_instance
.
updated_by
self
.
validated_data
[
"updated_by"
]
=
pending_instance
.
updated_by
...
@@ -167,4 +222,4 @@ class MyModelSerializer(MySerializerWithJSON):
...
@@ -167,4 +222,4 @@ class MyModelSerializer(MySerializerWithJSON):
pass
pass
self
.
set_model_attr_no_moder
(
moderated_and_updated
)
self
.
set_model_attr_no_moder
(
moderated_and_updated
)
return
super
(
MyModelSerializer
,
self
).
save
(
*
args
,
**
kwargs
)
return
super
().
save
(
*
args
,
**
kwargs
)
backend/backend_app/models/abstract/my_model/myModelVersionned.py
View file @
7266140c
from
django.contrib.contenttypes.models
import
ContentType
from
django.core
import
serializers
as
djangoSerializers
from
django.core.serializers.base
import
DeserializationError
import
reversion
from
backend_app.custom
import
MySerializerWithJSON
from
backend_app.models.abstract.my_model
import
(
from
backend_app.models.abstract.my_model
import
(
MyModel
,
MyModel
,
MyModelSerializer
,
MyModelSerializer
,
MyModelViewSet
,
MyModelViewSet
,
)
)
from
backend_app.signals.__squash_revision_by_user
import
new_revision_saved
from
backend_app.signals.__squash_revision_by_user
import
new_revision_saved
from
rest_framework
import
serializers
,
mixins
,
viewsets
import
reversion
from
reversion.models
import
Version
from
django.contrib.contenttypes.models
import
ContentType
from
django.core.serializers.base
import
DeserializationError
from
django.core
import
serializers
as
djangoSerializers
from
backend_app.utils
import
get_viewset_permissions
from
backend_app.utils
import
get_viewset_permissions
from
backend_app.custom
import
MySerializerWithJSON
from
rest_framework
import
mixins
,
serializers
,
viewsets
from
reversion.models
import
Version
class
MyModelVersionned
(
MyModel
):
class
MyModelVersionned
(
MyModel
):
"""
Custom MyModel that will be versionned in the app
"""
@
classmethod
@
classmethod
def
get_serializer
(
cls
):
def
get_serializer
(
cls
):
"""
"""
...
@@ -29,19 +34,36 @@ class MyModelVersionned(MyModel):
...
@@ -29,19 +34,36 @@ class MyModelVersionned(MyModel):
class
MyModelVersionnedSerializer
(
MyModelSerializer
):
class
MyModelVersionnedSerializer
(
MyModelSerializer
):
"""
Serializer for versionned models
"""
# Add a nb_versions field
nb_versions
=
serializers
.
SerializerMethodField
()
nb_versions
=
serializers
.
SerializerMethodField
()
# Add a content_type_id field to be able to find versions
content_type_id
=
serializers
.
SerializerMethodField
()
content_type_id
=
serializers
.
SerializerMethodField
()
def
get_nb_versions
(
self
,
obj
):
def
get_nb_versions
(
self
,
obj
):
"""
Serializer for the nb_version field
With a bit of optimization
"""
if
self
.
FORCE_FULL_DISPLAY
or
self
.
context
[
"view"
].
action
!=
"list"
:
if
self
.
FORCE_FULL_DISPLAY
or
self
.
context
[
"view"
].
action
!=
"list"
:
versions
=
Version
.
objects
.
get_for_object
(
obj
)
versions
=
Version
.
objects
.
get_for_object
(
obj
)
return
len
(
versions
)
return
len
(
versions
)
return
None
return
None
def
get_content_type_id
(
self
,
obj
):
def
get_content_type_id
(
self
,
obj
):
"""
Serializer for content type
"""
return
ContentType
.
objects
.
get_for_model
(
self
.
Meta
.
model
).
id
return
ContentType
.
objects
.
get_for_model
(
self
.
Meta
.
model
).
id
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
"""
Custom save function to use reversion.
"""
with
reversion
.
create_revision
():
with
reversion
.
create_revision
():
res
=
self
.
my_save
(
*
args
,
**
kwargs
)
res
=
self
.
my_save
(
*
args
,
**
kwargs
)
reversion
.
set_user
(
res
.
updated_by
)
reversion
.
set_user
(
res
.
updated_by
)
...
@@ -50,19 +72,29 @@ class MyModelVersionnedSerializer(MyModelSerializer):
...
@@ -50,19 +72,29 @@ class MyModelVersionnedSerializer(MyModelSerializer):
class
MyModelVersionnedViewSet
(
MyModelViewSet
):
class
MyModelVersionnedViewSet
(
MyModelViewSet
):
"""
Viewset for the versionned models
"""
serializer_class
=
MyModelVersionnedSerializer
serializer_class
=
MyModelVersionnedSerializer
class
VersionSerializer
(
MySerializerWithJSON
):
class
VersionSerializer
(
MySerializerWithJSON
):
"""
Custom serializer for the (reversion) version model
"""
data
=
serializers
.
SerializerMethodField
()
data
=
serializers
.
SerializerMethodField
()
def
get_data
(
self
,
obj
):
def
get_data
(
self
,
obj
):
"""
"""
Serilizer for the data field
TODO test
TODO test
"""
"""
data
=
obj
.
serialized_data
data
=
obj
.
serialized_data
try
:
try
:
# We try to deserialize the version
tmp
=
list
(
tmp
=
list
(
djangoSerializers
.
deserialize
(
obj
.
format
,
data
,
ignorenonexistent
=
True
)
djangoSerializers
.
deserialize
(
obj
.
format
,
data
,
ignorenonexistent
=
True
)
)[
0
]
)[
0
]
...
@@ -81,9 +113,12 @@ class VersionSerializer(MySerializerWithJSON):
...
@@ -81,9 +113,12 @@ class VersionSerializer(MySerializerWithJSON):
fields
=
(
"data"
,
"id"
)
fields
=
(
"data"
,
"id"
)
class
VersionViewSet
(
class
VersionViewSet
(
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
):
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
"""
):
# TODO better presentation
Viewset for the versions
TODO better presentation
"""
permission_classes
=
get_viewset_permissions
(
"VersionViewSet"
)
permission_classes
=
get_viewset_permissions
(
"VersionViewSet"
)
serializer_class
=
VersionSerializer
serializer_class
=
VersionSerializer
...
...
backend/backend_app/models/abstract/my_model/myModelViewSet.py
View file @
7266140c
from
.myModelSerializer
import
MyModelSerializer
from
backend_app.permissions
import
DEFAULT_VIEWSET_PERMISSIONS
from
backend_app.permissions
import
DEFAULT_VIEWSET_PERMISSIONS
from
rest_framework
import
viewsets
from
rest_framework
import
viewsets
from
.myModelSerializer
import
MyModelSerializer
class
MyModelViewSet
(
viewsets
.
ModelViewSet
):
class
MyModelViewSet
(
viewsets
.
ModelViewSet
):
"""
Custom default viewset
"""
serializer_class
=
MyModelSerializer
serializer_class
=
MyModelSerializer
permission_classes
=
DEFAULT_VIEWSET_PERMISSIONS
permission_classes
=
DEFAULT_VIEWSET_PERMISSIONS
# Class attribute to tell that return 1 element and not a list of element
# For example when querying userData, we don't specify the userId and query the viewset
# in list mode; still we want to return only one
LIST_SHOULD_BE_DETAIL
=
False
LIST_SHOULD_BE_DETAIL
=
False
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
response
=
super
(
viewsets
.
ModelViewSet
,
self
).
list
(
# pylint: disable=E1003
"""
request
,
*
args
,
**
kwargs
Extend the list function of the viewset class
)
# call the original 'list'
"""
response
=
super
().
list
(
request
,
*
args
,
**
kwargs
)
# call the original 'list'
if
self
.
LIST_SHOULD_BE_DETAIL
:
if
self
.
LIST_SHOULD_BE_DETAIL
:
if
len
(
response
.
data
)
==
0
:
if
len
(
response
.
data
)
==
0
:
...
...
backend/backend_app/models/abstract/my_model/pendingModeration.py
View file @
7266140c
from
django.db
import
models
from
rest_framework
import
serializers
,
viewsets
from
django.contrib.contenttypes.models
import
ContentType
from
django.contrib.contenttypes.fields
import
GenericForeignKey
from
backend_app.fields
import
JSONField
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
backend_app.utils
import
get_viewset_permissions
,
get_model_config
from
django.contrib.contenttypes.fields
import
GenericForeignKey
from
django.contrib.contenttypes.models
import
ContentType
from
django.db
import
models
from
backend_app.custom
import
MySerializerWithJSON
from
backend_app.custom
import
MySerializerWithJSON
from
backend_app.fields
import
JSONField
from
backend_app.utils
import
get_model_config
,
get_viewset_permissions
from
rest_framework
import
serializers
,
viewsets
class
PendingModeration
(
models
.
Model
):
class
PendingModeration
(
models
.
Model
):
"""
Model to hold models that are pending moderation.
"""
model_config
=
get_model_config
(
"PendingModeration"
)
model_config
=
get_model_config
(
"PendingModeration"
)
content_type
=
models
.
ForeignKey
(
ContentType
,
on_delete
=
models
.
CASCADE
)
content_type
=
models
.
ForeignKey
(
ContentType
,
on_delete
=
models
.
CASCADE
)
...
@@ -18,6 +23,7 @@ class PendingModeration(models.Model):
...
@@ -18,6 +23,7 @@ class PendingModeration(models.Model):
updated_by
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
CASCADE
)
updated_by
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
CASCADE
)
updated_on
=
models
.
DateTimeField
(
null
=
True
)
updated_on
=
models
.
DateTimeField
(
null
=
True
)
# Object pending moderation
new_object
=
JSONField
(
default
=
dict
)
new_object
=
JSONField
(
default
=
dict
)
class
Meta
:
class
Meta
:
...
@@ -25,6 +31,10 @@ class PendingModeration(models.Model):
...
@@ -25,6 +31,10 @@ class PendingModeration(models.Model):
class
PendingModerationSerializer
(
MySerializerWithJSON
):
class
PendingModerationSerializer
(
MySerializerWithJSON
):
"""
Serializer for the Pending Moderation Model
"""
content_type
=
serializers
.
CharField
(
read_only
=
True
)
content_type
=
serializers
.
CharField
(
read_only
=
True
)
object_id
=
serializers
.
CharField
(
read_only
=
True
)
object_id
=
serializers
.
CharField
(
read_only
=
True
)
...
@@ -39,6 +49,10 @@ class PendingModerationSerializer(MySerializerWithJSON):
...
@@ -39,6 +49,10 @@ class PendingModerationSerializer(MySerializerWithJSON):
class
PendingModerationViewSet
(
viewsets
.
ModelViewSet
):
class
PendingModerationViewSet
(
viewsets
.
ModelViewSet
):
"""
Viewset for the pending moderation model.
"""
permission_classes
=
get_viewset_permissions
(
"PendingModerationViewSet"
)
permission_classes
=
get_viewset_permissions
(
"PendingModerationViewSet"
)
queryset
=
PendingModeration
.
objects
.
all
()
# pylint: disable=E1101
queryset
=
PendingModeration
.
objects
.
all
()
# pylint: disable=E1101
serializer_class
=
PendingModerationSerializer
serializer_class
=
PendingModerationSerializer
backend/backend_app/models/abstract/scholarship/scholarship.py
View file @
7266140c
from
django.core.validators
import
MinValueValidator
from
django.db
import
models
from
django.db
import
models
from
backend_app.models.abstract.basic_module
import
(
from
backend_app.models.abstract.basic_module
import
(
BasicModule
,
BasicModule
,
BasicModuleSerializer
,