Browse Source

Merge pull request #1656 from doccano/enhancement/separateExampleApp

[Enhancement] Separate example app
pull/1657/head
Hiroki Nakayama 2 years ago
committed by GitHub
parent
commit
6d3ac55da6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 439 additions and 212 deletions
  1. 18
      backend/api/admin.py
  2. 46
      backend/api/migrations/0034_auto_20220128_0246.py
  3. 34
      backend/api/migrations/0035_auto_20220128_0246.py
  4. 79
      backend/api/models.py
  5. 9
      backend/api/permissions.py
  6. 50
      backend/api/serializers.py
  7. 27
      backend/api/urls.py
  8. 1
      backend/app/settings.py
  9. 1
      backend/app/urls.py
  10. 3
      backend/auto_labeling/pipeline/labels.py
  11. 3
      backend/data_export/pipeline/repositories.py
  12. 3
      backend/data_import/pipeline/data.py
  13. 3
      backend/data_import/pipeline/writers.py
  14. 3
      backend/data_import/tests/test_tasks.py
  15. 0
      backend/examples/__init__.py
  16. 19
      backend/examples/admin.py
  17. 6
      backend/examples/apps.py
  18. 0
      backend/examples/filters.py
  19. 0
      backend/examples/managers.py
  20. 79
      backend/examples/migrations/0001_initial.py
  21. 0
      backend/examples/migrations/__init__.py
  22. 83
      backend/examples/models.py
  23. 10
      backend/examples/permissions.py
  24. 50
      backend/examples/serializers.py
  25. 0
      backend/examples/tests/__init__.py
  26. 3
      backend/examples/tests/test_comment.py
  27. 5
      backend/examples/tests/test_document.py
  28. 3
      backend/examples/tests/test_example_state.py
  29. 7
      backend/examples/tests/test_filters.py
  30. 6
      backend/examples/tests/test_models.py
  31. 34
      backend/examples/urls.py
  32. 0
      backend/examples/views/__init__.py
  33. 7
      backend/examples/views/comment.py
  34. 8
      backend/examples/views/example.py
  35. 6
      backend/examples/views/example_state.py
  36. 38
      backend/labels/migrations/0004_auto_20220128_0246.py
  37. 3
      backend/labels/models.py
  38. 2
      backend/labels/serializers.py
  39. 2
      backend/metrics/views.py

18
backend/api/admin.py

@ -1,13 +1,7 @@
from django.contrib import admin
from .models import (Comment, Example, Project, Seq2seqProject,
SequenceLabelingProject, Tag, TextClassificationProject)
class ExampleAdmin(admin.ModelAdmin):
list_display = ('text', 'project', 'meta')
ordering = ('project',)
search_fields = ('text',)
from .models import (Project, Seq2seqProject, SequenceLabelingProject, Tag,
TextClassificationProject)
class ProjectAdmin(admin.ModelAdmin):
@ -22,16 +16,8 @@ class TagAdmin(admin.ModelAdmin):
search_fields = ('text',)
class CommentAdmin(admin.ModelAdmin):
list_display = ('user', 'example', 'text', 'created_at', )
ordering = ('user', 'created_at', )
search_fields = ('user',)
admin.site.register(Example, ExampleAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(TextClassificationProject, ProjectAdmin)
admin.site.register(SequenceLabelingProject, ProjectAdmin)
admin.site.register(Seq2seqProject, ProjectAdmin)
admin.site.register(Comment, CommentAdmin)
admin.site.register(Tag, TagAdmin)

46
backend/api/migrations/0034_auto_20220128_0246.py

@ -0,0 +1,46 @@
# Generated by Django 3.2.11 on 2022-01-28 02:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0033_auto_20220127_0654'),
]
operations = [
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.RemoveField(
model_name='example',
name='annotations_approved_by',
),
migrations.RemoveField(
model_name='example',
name='project',
),
migrations.AlterUniqueTogether(
name='examplestate',
unique_together=None,
),
migrations.RemoveField(
model_name='examplestate',
name='confirmed_by',
),
migrations.RemoveField(
model_name='examplestate',
name='example',
),
migrations.DeleteModel(
name='Comment',
),
],
database_operations=[
migrations.AlterModelTable(
name='Comment',
table='examples_comment'
)
]
)
]

34
backend/api/migrations/0035_auto_20220128_0246.py

@ -0,0 +1,34 @@
# Generated by Django 3.2.11 on 2022-01-28 02:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0034_auto_20220128_0246'),
('labels', '0004_auto_20220128_0246'),
]
operations = [
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.DeleteModel(
name='Example',
),
migrations.DeleteModel(
name='ExampleState',
),
],
database_operations=[
migrations.AlterModelTable(
name='Example',
table='examples_example'
),
migrations.AlterModelTable(
name='ExampleState',
table='examples_examplestate'
)
]
)
]

79
backend/api/models.py

@ -1,12 +1,9 @@
import abc
import uuid
from django.contrib.auth.models import User
from django.db import models
from polymorphic.models import PolymorphicModel
from .managers import ExampleManager, ExampleStateManager
DOCUMENT_CLASSIFICATION = 'DocumentClassification'
SEQUENCE_LABELING = 'SequenceLabeling'
SEQ2SEQ = 'Seq2seq'
@ -148,82 +145,6 @@ class ImageClassificationProject(Project):
return True
class Example(models.Model):
objects = ExampleManager()
uuid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True, unique=True)
meta = models.JSONField(default=dict)
filename = models.FileField(default='.', max_length=1024)
project = models.ForeignKey(
to=Project,
on_delete=models.CASCADE,
related_name='examples'
)
annotations_approved_by = models.ForeignKey(
to=User,
on_delete=models.SET_NULL,
null=True,
blank=True
)
text = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(auto_now=True)
@property
def comment_count(self):
return Comment.objects.filter(example=self.id).count()
@property
def data(self):
if self.project.is_text_project:
return self.text
else:
return str(self.filename)
class Meta:
ordering = ['created_at']
class ExampleState(models.Model):
objects = ExampleStateManager()
example = models.ForeignKey(
to=Example,
on_delete=models.CASCADE,
related_name='states'
)
confirmed_by = models.ForeignKey(
to=User,
on_delete=models.CASCADE
)
confirmed_at = models.DateTimeField(auto_now=True)
class Meta:
unique_together = (('example', 'confirmed_by'),)
class Comment(models.Model):
text = models.TextField()
example = models.ForeignKey(
to=Example,
on_delete=models.CASCADE,
related_name='comments'
)
user = models.ForeignKey(
to=User,
on_delete=models.CASCADE,
null=True
)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(auto_now=True)
@property
def username(self):
return self.user.username
class Meta:
ordering = ['created_at']
class Tag(models.Model):
text = models.TextField()
project = models.ForeignKey(

9
backend/api/permissions.py

@ -1,15 +1,6 @@
from rest_framework.permissions import BasePermission
class IsOwnComment(BasePermission):
@classmethod
def has_object_permission(cls, request, view, obj):
if request.user.is_superuser:
return True
return obj.user.id == request.user.id
class IsStaff(BasePermission):
def has_permission(self, request, view):
if request.user.is_superuser or request.user.is_staff:

50
backend/api/serializers.py

@ -1,21 +1,12 @@
from rest_framework import serializers
from rest_polymorphic.serializers import PolymorphicSerializer
from .models import (Comment, Example, ExampleState,
ImageClassificationProject,
from .models import (ImageClassificationProject,
IntentDetectionAndSlotFillingProject, Project,
Seq2seqProject, SequenceLabelingProject,
Speech2textProject, Tag, TextClassificationProject)
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'user', 'username', 'example', 'text', 'created_at', )
read_only_fields = ('user', 'example')
class TagSerializer(serializers.ModelSerializer):
class Meta:
@ -24,45 +15,6 @@ class TagSerializer(serializers.ModelSerializer):
read_only_fields = ('id', 'project')
class ExampleSerializer(serializers.ModelSerializer):
annotation_approver = serializers.SerializerMethodField()
is_confirmed = serializers.SerializerMethodField()
@classmethod
def get_annotation_approver(cls, instance):
approver = instance.annotations_approved_by
return approver.username if approver else None
def get_is_confirmed(self, instance):
user = self.context.get('request').user
if instance.project.collaborative_annotation:
states = instance.states.all()
else:
states = instance.states.filter(confirmed_by_id=user.id)
return states.count() > 0
class Meta:
model = Example
fields = [
'id',
'filename',
'meta',
'annotation_approver',
'comment_count',
'text',
'is_confirmed'
]
read_only_fields = ['filename', 'is_confirmed']
class ExampleStateSerializer(serializers.ModelSerializer):
class Meta:
model = ExampleState
fields = ('id', 'example', 'confirmed_by')
read_only_fields = ('id', 'example', 'confirmed_by')
class ProjectSerializer(serializers.ModelSerializer):
tags = TagSerializer(many=True, required=False)

27
backend/api/urls.py

@ -1,18 +1,8 @@
from django.urls import include, path
from .views import comment, example, example_state, health, project, tag, task
from .views import health, project, tag, task
urlpatterns_project = [
path(
route='examples',
view=example.ExampleList.as_view(),
name='example_list'
),
path(
route='examples/<int:example_id>',
view=example.ExampleDetail.as_view(),
name='example_detail'
),
path(
route='tags',
view=tag.TagList.as_view(),
@ -23,21 +13,6 @@ urlpatterns_project = [
view=tag.TagDetail.as_view(),
name='tag_detail'
),
path(
route='comments',
view=comment.CommentList.as_view(),
name='comment_list'
),
path(
route='comments/<int:comment_id>',
view=comment.CommentDetail.as_view(),
name='comment_detail'
),
path(
route='examples/<int:example_id>/states',
view=example_state.ExampleStateList.as_view(),
name='example_state_list'
),
]
urlpatterns = [

1
backend/app/settings.py

@ -61,6 +61,7 @@ INSTALLED_APPS = [
'auto_labeling.apps.AutoLabelingConfig',
'labels.apps.LabelsConfig',
'label_types.apps.LabelTypesConfig',
'examples.apps.ExamplesConfig',
'rest_framework',
'rest_framework.authtoken',
'django_filters',

1
backend/app/urls.py

@ -48,6 +48,7 @@ urlpatterns += [
path('v1/projects/<int:project_id>/', include('members.urls')),
path('v1/projects/<int:project_id>/metrics/', include('metrics.urls')),
path('v1/projects/<int:project_id>/', include('auto_labeling.urls')),
path('v1/projects/<int:project_id>/', include('examples.urls')),
path('v1/projects/<int:project_id>/', include('labels.urls')),
path('v1/projects/<int:project_id>/', include('label_types.urls')),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),

3
backend/auto_labeling/pipeline/labels.py

@ -4,7 +4,8 @@ from typing import List
from auto_labeling_pipeline.labels import Labels
from django.contrib.auth.models import User
from api.models import Project, Example
from api.models import Project
from examples.models import Example
from label_types.models import CategoryType, SpanType
from labels.models import Label, Category, Span, TextLabel

3
backend/data_export/pipeline/repositories.py

@ -3,7 +3,8 @@ import itertools
from collections import defaultdict
from typing import Dict, Iterator, List
from api.models import Example, Project
from api.models import Project
from examples.models import Example
from .data import Record

3
backend/data_import/pipeline/data.py

@ -4,7 +4,8 @@ from typing import Any, Dict
from pydantic import BaseModel, validator
from api.models import Example, Project
from api.models import Project
from examples.models import Example
class BaseData(BaseModel, abc.ABC):

3
backend/data_import/pipeline/writers.py

@ -5,7 +5,8 @@ from typing import Any, Dict, List
from django.conf import settings
from api.models import Example, Project
from api.models import Project
from examples.models import Example
from label_types.models import CategoryType, SpanType
from .exceptions import FileParseException
from .readers import BaseReader

3
backend/data_import/tests/test_tasks.py

@ -5,7 +5,8 @@ from django.test import TestCase
from data_import.celery_tasks import import_dataset
from api.models import (DOCUMENT_CLASSIFICATION,
INTENT_DETECTION_AND_SLOT_FILLING, SEQ2SEQ,
SEQUENCE_LABELING, Example)
SEQUENCE_LABELING)
from examples.models import Example
from label_types.models import CategoryType, SpanType
from labels.models import Category, Span
from api.tests.api.utils import prepare_project

0
backend/examples/__init__.py

19
backend/examples/admin.py

@ -0,0 +1,19 @@
from django.contrib import admin
from .models import Example, Comment
class ExampleAdmin(admin.ModelAdmin):
list_display = ('text', 'project', 'meta')
ordering = ('project',)
search_fields = ('text',)
class CommentAdmin(admin.ModelAdmin):
list_display = ('user', 'example', 'text', 'created_at', )
ordering = ('user', 'created_at', )
search_fields = ('user',)
admin.site.register(Example, ExampleAdmin)
admin.site.register(Comment, CommentAdmin)

6
backend/examples/apps.py

@ -0,0 +1,6 @@
from django.apps import AppConfig
class ExamplesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'examples'

backend/api/filters.py → backend/examples/filters.py

backend/api/managers.py → backend/examples/managers.py

79
backend/examples/migrations/0001_initial.py

@ -0,0 +1,79 @@
# Generated by Django 3.2.11 on 2022-01-28 02:46
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('api', '0034_auto_20220128_0246'),
]
operations = [
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.CreateModel(
name='Example',
fields=[
('id',
models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, unique=True)),
('meta', models.JSONField(default=dict)),
('filename', models.FileField(default='.', max_length=1024, upload_to='')),
('text', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('annotations_approved_by',
models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL)),
('project',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='examples',
to='api.project')),
],
options={
'ordering': ['created_at'],
},
),
migrations.CreateModel(
name='Comment',
fields=[
('id',
models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('example',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments',
to='examples.example')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['created_at'],
},
),
migrations.CreateModel(
name='ExampleState',
fields=[
('id',
models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('confirmed_at', models.DateTimeField(auto_now=True)),
('confirmed_by',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('example',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='states',
to='examples.example')),
],
options={
'unique_together': {('example', 'confirmed_by')},
},
),
]
)
]

0
backend/examples/migrations/__init__.py

83
backend/examples/models.py

@ -0,0 +1,83 @@
import uuid
from django.contrib.auth.models import User
from django.db import models
from api.models import Project
from .managers import ExampleManager, ExampleStateManager
class Example(models.Model):
objects = ExampleManager()
uuid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True, unique=True)
meta = models.JSONField(default=dict)
filename = models.FileField(default='.', max_length=1024)
project = models.ForeignKey(
to=Project,
on_delete=models.CASCADE,
related_name='examples'
)
annotations_approved_by = models.ForeignKey(
to=User,
on_delete=models.SET_NULL,
null=True,
blank=True
)
text = models.TextField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(auto_now=True)
@property
def comment_count(self):
return Comment.objects.filter(example=self.id).count()
@property
def data(self):
if self.project.is_text_project:
return self.text
else:
return str(self.filename)
class Meta:
ordering = ['created_at']
class ExampleState(models.Model):
objects = ExampleStateManager()
example = models.ForeignKey(
to=Example,
on_delete=models.CASCADE,
related_name='states'
)
confirmed_by = models.ForeignKey(
to=User,
on_delete=models.CASCADE
)
confirmed_at = models.DateTimeField(auto_now=True)
class Meta:
unique_together = (('example', 'confirmed_by'),)
class Comment(models.Model):
text = models.TextField()
example = models.ForeignKey(
to=Example,
on_delete=models.CASCADE,
related_name='comments'
)
user = models.ForeignKey(
to=User,
on_delete=models.CASCADE,
null=True
)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(auto_now=True)
@property
def username(self):
return self.user.username
class Meta:
ordering = ['created_at']

10
backend/examples/permissions.py

@ -0,0 +1,10 @@
from rest_framework.permissions import BasePermission
class IsOwnComment(BasePermission):
@classmethod
def has_object_permission(cls, request, view, obj):
if request.user.is_superuser:
return True
return obj.user.id == request.user.id

50
backend/examples/serializers.py

@ -0,0 +1,50 @@
from rest_framework import serializers
from .models import Example, ExampleState, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'user', 'username', 'example', 'text', 'created_at', )
read_only_fields = ('user', 'example')
class ExampleSerializer(serializers.ModelSerializer):
annotation_approver = serializers.SerializerMethodField()
is_confirmed = serializers.SerializerMethodField()
@classmethod
def get_annotation_approver(cls, instance):
approver = instance.annotations_approved_by
return approver.username if approver else None
def get_is_confirmed(self, instance):
user = self.context.get('request').user
if instance.project.collaborative_annotation:
states = instance.states.all()
else:
states = instance.states.filter(confirmed_by_id=user.id)
return states.count() > 0
class Meta:
model = Example
fields = [
'id',
'filename',
'meta',
'annotation_approver',
'comment_count',
'text',
'is_confirmed'
]
read_only_fields = ['filename', 'is_confirmed']
class ExampleStateSerializer(serializers.ModelSerializer):
class Meta:
model = ExampleState
fields = ('id', 'example', 'confirmed_by')
read_only_fields = ('id', 'example', 'confirmed_by')

0
backend/examples/tests/__init__.py

backend/api/tests/api/test_comment.py → backend/examples/tests/test_comment.py

@ -1,8 +1,7 @@
from rest_framework import status
from rest_framework.reverse import reverse
from .utils import (CRUDMixin, make_comment, make_doc, make_user,
prepare_project)
from api.tests.api.utils import (CRUDMixin, make_comment, make_doc, make_user, prepare_project)
class TestCommentListDocAPI(CRUDMixin):

backend/api/tests/api/test_document.py → backend/examples/tests/test_document.py

@ -4,9 +4,8 @@ from rest_framework import status
from rest_framework.reverse import reverse
from api.models import DOCUMENT_CLASSIFICATION
from .utils import (CRUDMixin, assign_user_to_role, make_doc,
make_example_state, make_user, prepare_project)
from api.tests.api.utils import (CRUDMixin, assign_user_to_role, make_doc,
make_example_state, make_user, prepare_project)
class TestExampleListAPI(CRUDMixin):

backend/api/tests/api/test_example_state.py → backend/examples/tests/test_example_state.py

@ -1,8 +1,7 @@
from rest_framework import status
from rest_framework.reverse import reverse
from .utils import (CRUDMixin, make_doc, make_example_state, make_user,
prepare_project)
from api.tests.api.utils import (CRUDMixin, make_doc, make_example_state, make_user, prepare_project)
class TestExampleStateList(CRUDMixin):

backend/api/tests/test_filters.py → backend/examples/tests/test_filters.py

@ -2,10 +2,9 @@ from unittest.mock import MagicMock
from django.test import TestCase
from api.filters import ExampleFilter
from api.models import Example
from .api.utils import make_doc, make_example_state, prepare_project
from api.tests.api.utils import make_doc, make_example_state, prepare_project
from examples.models import Example
from examples.filters import ExampleFilter
class TestFilterMixin(TestCase):

backend/api/tests/test_models.py → backend/examples/tests/test_models.py

@ -1,9 +1,9 @@
from django.test import TestCase
from model_mommy import mommy
from api.models import IMAGE_CLASSIFICATION, SEQUENCE_LABELING, ExampleState
from .api.utils import prepare_project
from api.models import IMAGE_CLASSIFICATION, SEQUENCE_LABELING
from api.tests.api.utils import prepare_project
from examples.models import ExampleState
class TestExampleState(TestCase):

34
backend/examples/urls.py

@ -0,0 +1,34 @@
from django.urls import path
from .views.example import ExampleList, ExampleDetail
from .views.comment import CommentList, CommentDetail
from .views.example_state import ExampleStateList
urlpatterns = [
path(
route='examples',
view=ExampleList.as_view(),
name='example_list'
),
path(
route='examples/<int:example_id>',
view=ExampleDetail.as_view(),
name='example_detail'
),
path(
route='comments',
view=CommentList.as_view(),
name='comment_list'
),
path(
route='comments/<int:comment_id>',
view=CommentDetail.as_view(),
name='comment_detail'
),
path(
route='examples/<int:example_id>/states',
view=ExampleStateList.as_view(),
name='example_state_list'
),
]

0
backend/examples/views/__init__.py

backend/api/views/comment.py → backend/examples/views/comment.py

@ -4,10 +4,9 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from members.permissions import IsInProjectOrAdmin
from ..models import Comment
from ..permissions import IsOwnComment
from ..serializers import CommentSerializer
from examples.models import Comment
from examples.permissions import IsOwnComment
from examples.serializers import CommentSerializer
class CommentList(generics.ListCreateAPIView):

backend/api/views/example.py → backend/examples/views/example.py

@ -7,12 +7,12 @@ from rest_framework import filters, generics, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from api.models import Project
from examples.filters import ExampleFilter
from examples.models import Example
from examples.serializers import ExampleSerializer
from members.permissions import IsInProjectReadOnlyOrAdmin
from ..filters import ExampleFilter
from ..models import Example, Project
from ..serializers import ExampleSerializer
class ExampleList(generics.ListCreateAPIView):
serializer_class = ExampleSerializer

backend/api/views/example_state.py → backend/examples/views/example_state.py

@ -2,11 +2,11 @@ from django.shortcuts import get_object_or_404
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from api.models import Project
from examples.models import Example, ExampleState
from examples.serializers import ExampleStateSerializer
from members.permissions import IsInProjectOrAdmin
from ..models import Example, ExampleState, Project
from ..serializers import ExampleStateSerializer
class ExampleStateList(generics.ListCreateAPIView):
serializer_class = ExampleStateSerializer

38
backend/labels/migrations/0004_auto_20220128_0246.py

@ -0,0 +1,38 @@
# Generated by Django 3.2.11 on 2022-01-28 02:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('examples', '0001_initial'),
('labels', '0003_auto_20220127_0654'),
]
operations = [
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.AlterField(
model_name='category',
name='example',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='categories',
to='examples.example'),
),
migrations.AlterField(
model_name='span',
name='example',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='spans',
to='examples.example'),
),
migrations.AlterField(
model_name='textlabel',
name='example',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='texts',
to='examples.example'),
),
],
database_operations=[]
)
]

3
backend/labels/models.py

@ -3,7 +3,8 @@ from django.core.exceptions import ValidationError
from django.db import models
from .managers import LabelManager, CategoryManager, SpanManager, TextLabelManager
from api.models import Example, Project
from api.models import Project
from examples.models import Example
from label_types.models import CategoryType, SpanType, RelationType

2
backend/labels/serializers.py

@ -1,6 +1,6 @@
from rest_framework import serializers
from api.models import Example
from examples.models import Example
from label_types.models import CategoryType, SpanType
from .models import Category, Span, TextLabel, Relation

2
backend/metrics/views.py

@ -5,7 +5,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from api.models import Example, ExampleState
from examples.models import Example, ExampleState
from label_types.models import LabelType, CategoryType, SpanType
from labels.models import Label, Category, Span
from members.models import Member

Loading…
Cancel
Save