Commit df9317ac366977185d2d4f628991d9c4d02d97b5

Authored by janek@kublik
1 parent ad31813d

migracja Cell, TableHeader

--HG--
branch : beta
common/util.py
@@ -139,6 +139,11 @@ class FakeQueryset(list): @@ -139,6 +139,11 @@ class FakeQueryset(list):
139 def all(self): 139 def all(self):
140 return self 140 return self
141 141
  142 + def iterator(self):
  143 + return iter(self)
  144 +
  145 + _prefetch_related_lookups = False
  146 +
142 147
143 def format_date(date): 148 def format_date(date):
144 return date.strftime(force_unicode(_('%Y/%m/%d %I:%M %p'))) 149 return date.strftime(force_unicode(_('%Y/%m/%d %I:%M %p')))
dictionary/management/commands/stale/convert_tables.py
@@ -3,7 +3,8 @@ from django.core.management import BaseCommand @@ -3,7 +3,8 @@ from django.core.management import BaseCommand
3 from common.util import GroupDict 3 from common.util import GroupDict
4 from dictionary.models import Cell, TableTemplate, PatternType, TableTemplate, TableCell, TableHeader, \ 4 from dictionary.models import Cell, TableTemplate, PatternType, TableTemplate, TableCell, TableHeader, \
5 TableHeader, LexemeAttribute, ExportCell, InflectionCharacteristic, LexemeAttributeValue 5 TableHeader, LexemeAttribute, ExportCell, InflectionCharacteristic, LexemeAttributeValue
6 -from tables.models import Variant, TableTemplate 6 +from tables.models import Variant, TableTemplate, Cell, TableCell, ExportCell, \
  7 + TableHeader
7 from patterns.models import InflectionType, PatternType 8 from patterns.models import InflectionType, PatternType
8 9
9 10
dictionary/management/commands/stale/export_variant.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 from django.core.management import BaseCommand 2 from django.core.management import BaseCommand
3 from common.util import uniprint 3 from common.util import uniprint
4 -from dictionary.models import Cell 4 +from tables.models import Cell
5 5
6 6
7 class Command(BaseCommand): 7 class Command(BaseCommand):
dictionary/management/commands/stale/import_variant.py
@@ -5,7 +5,7 @@ from django.core.management.base import BaseCommand @@ -5,7 +5,7 @@ from django.core.management.base import BaseCommand
5 from common.util import uniopen 5 from common.util import uniopen
6 from dictionary.models import TableTemplate, Cell, TableCell, PartOfSpeech, \ 6 from dictionary.models import TableTemplate, Cell, TableCell, PartOfSpeech, \
7 PatternType, InflectionCharacteristic 7 PatternType, InflectionCharacteristic
8 -from tables.models import Variant, TableTemplate 8 +from tables.models import Variant, TableTemplate, Cell, TableCell
9 from patterns.models import BaseFormLabel, PatternType 9 from patterns.models import BaseFormLabel, PatternType
10 10
11 11
dictionary/management/commands/stale/table_analyzer.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 from django.core.management import BaseCommand 2 from django.core.management import BaseCommand
3 from dictionary.models import Cell 3 from dictionary.models import Cell
4 -from tables.models import Variant 4 +from tables.models import Variant, Cell
5 5
6 6
7 class Command(BaseCommand): 7 class Command(BaseCommand):
dictionary/migrations/0016_auto_20151213_1400.py 0 โ†’ 100644
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import migrations, models
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('dictionary', '0015_auto_20151213_1328'),
  11 + ]
  12 +
  13 + database_operations = [
  14 + migrations.AlterModelTable('tablecell', 'tables_tablecell'),
  15 + migrations.AlterModelTable('exportcell', 'tables_exportcell'),
  16 + migrations.AlterModelTable('tableheader', 'tables_tableheader'),
  17 + ]
  18 +
  19 + operations = [
  20 + migrations.SeparateDatabaseAndState(
  21 + database_operations=database_operations)
  22 + ]
dictionary/migrations/0017_auto_20151213_1400.py 0 โ†’ 100644
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import migrations, models
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('dictionary', '0016_auto_20151213_1400'),
  11 + ('tables', '0003_exportcell_tablecell_tableheader'),
  12 + ]
  13 +
  14 + state_operations = [
  15 + migrations.RemoveField(
  16 + model_name='exportcell',
  17 + name='attribute_values',
  18 + ),
  19 + migrations.RemoveField(
  20 + model_name='exportcell',
  21 + name='base_form_label',
  22 + ),
  23 + migrations.RemoveField(
  24 + model_name='exportcell',
  25 + name='genders',
  26 + ),
  27 + migrations.RemoveField(
  28 + model_name='exportcell',
  29 + name='pattern_types',
  30 + ),
  31 + migrations.RemoveField(
  32 + model_name='exportcell',
  33 + name='table_template',
  34 + ),
  35 + migrations.RemoveField(
  36 + model_name='tablecell',
  37 + name='attribute_values',
  38 + ),
  39 + migrations.RemoveField(
  40 + model_name='tablecell',
  41 + name='base_form_label',
  42 + ),
  43 + migrations.RemoveField(
  44 + model_name='tablecell',
  45 + name='genders',
  46 + ),
  47 + migrations.RemoveField(
  48 + model_name='tablecell',
  49 + name='marked_attribute_values',
  50 + ),
  51 + migrations.RemoveField(
  52 + model_name='tablecell',
  53 + name='pattern_types',
  54 + ),
  55 + migrations.RemoveField(
  56 + model_name='tablecell',
  57 + name='table_template',
  58 + ),
  59 + migrations.RemoveField(
  60 + model_name='tableheader',
  61 + name='attribute_values',
  62 + ),
  63 + migrations.RemoveField(
  64 + model_name='tableheader',
  65 + name='genders',
  66 + ),
  67 + migrations.RemoveField(
  68 + model_name='tableheader',
  69 + name='pattern_types',
  70 + ),
  71 + migrations.RemoveField(
  72 + model_name='tableheader',
  73 + name='table_template',
  74 + ),
  75 + migrations.DeleteModel(
  76 + name='ExportCell',
  77 + ),
  78 + migrations.DeleteModel(
  79 + name='TableCell',
  80 + ),
  81 + migrations.DeleteModel(
  82 + name='TableHeader',
  83 + ),
  84 + ]
  85 +
  86 + operations = [
  87 + migrations.SeparateDatabaseAndState(state_operations=state_operations),
  88 + ]
dictionary/models.py
@@ -793,19 +793,6 @@ class LexemeInflectionPattern(Model): @@ -793,19 +793,6 @@ class LexemeInflectionPattern(Model):
793 ordering = ['index'] 793 ordering = ['index']
794 794
795 795
796 -def combine_qualifiers(lip_qualifiers, e_qualifiers):  
797 - # qualifiers = set(l_qualifiers)  
798 - if not lip_qualifiers:  
799 - return e_qualifiers  
800 - qualifiers = set()  
801 - for q in list(lip_qualifiers) + list(e_qualifiers):  
802 - if q.exclusion_class:  
803 - excluded = set(q.exclusion_class.qualifier_set.all())  
804 - qualifiers -= excluded  
805 - qualifiers.add(q)  
806 - return qualifiers  
807 -  
808 -  
809 # Sluzy do doczepienia flag do poszczegolnych form 796 # Sluzy do doczepienia flag do poszczegolnych form
810 # poszczegolnych leksemow 797 # poszczegolnych leksemow
811 # class UncommonForm(Model): 798 # class UncommonForm(Model):
@@ -1009,139 +996,6 @@ class CrossReference(Model): @@ -1009,139 +996,6 @@ class CrossReference(Model):
1009 db_table = 'odsylacze' 996 db_table = 'odsylacze'
1010 997
1011 998
1012 -class Cell(Model):  
1013 - base_form_label = ForeignKey(BaseFormLabel)  
1014 - prefix = CharField(max_length=20, blank=True)  
1015 - suffix = CharField(max_length=20, blank=True)  
1016 -  
1017 - def get_index(self):  
1018 - return None  
1019 -  
1020 - def get_qualifier(self):  
1021 - return ''  
1022 -  
1023 - def get_marked_attribute_values(self):  
1024 - return set()  
1025 -  
1026 - def forms(self, base_endings=None, separator=u'', root=u'',  
1027 - lip_qualifiers=None, lip_index=0, qualifiers=None,  
1028 - edit_view=False, span=False, depr=None, cell_qualifier=False):  
1029 - if qualifiers:  
1030 - qualifiers_set = set(qualifiers)  
1031 -  
1032 - def filter_quals(quals):  
1033 - if not qualifiers:  
1034 - return set(quals)  
1035 - else:  
1036 - return set(quals) & qualifiers_set  
1037 -  
1038 - if lip_qualifiers and not edit_view:  
1039 - # l_qual = filter_quals(lexeme_qualifiers)  
1040 - lip_qual = filter_quals(lip_qualifiers)  
1041 - else:  
1042 - lip_qual = set()  
1043 - endings = base_endings[self.base_form_label]  
1044 - if span:  
1045 - form_template = (  
1046 - '<span class="root">%s</span>'  
1047 - '%s<span class="ending">%s</span>')  
1048 - else:  
1049 - form_template = '%s%s%s'  
1050 - if self.prefix and span:  
1051 - form_template = '<span class="prefix">%s</span>' + form_template  
1052 - else:  
1053 - form_template = '%s' + form_template  
1054 - if self.suffix and span:  
1055 - form_template += '<span class="suffix">%s</span>'  
1056 - else:  
1057 - form_template += '%s'  
1058 - if depr and depr in self.get_marked_attribute_values():  
1059 - form_template = (  
1060 - '<span class="marked-form" title="%s">%s</span>'  
1061 - % (depr.display_value, form_template))  
1062 - if cell_qualifier and self.get_qualifier():  
1063 - form_template += (  
1064 - ' <span class="cell-qualifier">%s</span>'  
1065 - % self.get_qualifier())  
1066 - forms = [  
1067 - (  
1068 - (self.get_index(), lip_index, ending.index),  
1069 - (form_template % (  
1070 - self.prefix, root, separator, ending.string, self.suffix)),  
1071 - combine_qualifiers(  
1072 - lip_qual, filter_quals(ending.qualifiers.all())),  
1073 - )  
1074 - for ending in endings  
1075 - ]  
1076 - return forms  
1077 -  
1078 - class Meta:  
1079 - abstract = True  
1080 -  
1081 -  
1082 -class TableCell(Cell):  
1083 - table_template = ForeignKey('tables.TableTemplate', related_name='table_cells')  
1084 - pattern_types = ManyToManyField(PatternType)  
1085 - genders = ManyToManyField(Gender)  
1086 - attribute_values = ManyToManyField(  
1087 - LexemeAttributeValue, related_name='table_cells')  
1088 - marked_attribute_values = ManyToManyField(  
1089 - LexemeAttributeValue, related_name='marked_cells')  
1090 - qualifier = CharField(max_length=128, blank=True)  
1091 - row = IntegerField()  
1092 - col = IntegerField()  
1093 - rowspan = IntegerField()  
1094 - colspan = IntegerField()  
1095 - index = IntegerField()  
1096 -  
1097 - def get_index(self):  
1098 - return self.index  
1099 -  
1100 - def get_qualifier(self):  
1101 - return self.qualifier  
1102 -  
1103 - def get_marked_attribute_values(self):  
1104 - return set(self.marked_attribute_values.all())  
1105 -  
1106 - def __unicode__(self):  
1107 - return '%s:%s %s-%s-%s (%s, %s)' % (  
1108 - self.table_template.variant_id, self.table_template.name,  
1109 - self.prefix, self.base_form_label.symbol, self.suffix,  
1110 - self.row, self.col)  
1111 -  
1112 -  
1113 -class ExportCell(Cell):  
1114 - table_template = ForeignKey('tables.TableTemplate', related_name='export_cells')  
1115 - pattern_types = ManyToManyField(PatternType)  
1116 - genders = ManyToManyField(Gender)  
1117 - attribute_values = ManyToManyField(LexemeAttributeValue)  
1118 - tag_template = TextField()  
1119 -  
1120 - def __unicode__(self):  
1121 - return '%s:%s %s-%s-%s (%s)' % (  
1122 - self.table_template.variant.id, self.table_template.name,  
1123 - self.prefix, self.base_form_label.symbol, self.suffix,  
1124 - self.tag_template)  
1125 -  
1126 -  
1127 -class TableHeader(Model):  
1128 - table_template = ForeignKey('tables.TableTemplate', related_name='headers')  
1129 - pattern_types = ManyToManyField(PatternType)  
1130 - genders = ManyToManyField(Gender)  
1131 - attribute_values = ManyToManyField(LexemeAttributeValue)  
1132 - row = IntegerField()  
1133 - col = IntegerField()  
1134 - rowspan = IntegerField()  
1135 - colspan = IntegerField()  
1136 - label = CharField(max_length=64, blank=True, db_column='nagl')  
1137 - css_class = CharField(max_length=8, db_column='styl')  
1138 -  
1139 - def __unicode__(self):  
1140 - return u'%s:%s %s (%s, %s)' % (  
1141 - self.table_template.variant_id, self.table_template.name,  
1142 - self.label, self.row, self.col)  
1143 -  
1144 -  
1145 # na szybko i brudno 999 # na szybko i brudno
1146 class ParadygmatyWSJP(Model): 1000 class ParadygmatyWSJP(Model):
1147 wariant = CharField(max_length=4) 1001 wariant = CharField(max_length=4)
management/ajax_table_view.py
@@ -5,9 +5,9 @@ from dictionary.forms import LexemeClosedAttributeForm @@ -5,9 +5,9 @@ from dictionary.forms import LexemeClosedAttributeForm
5 from management.forms import CellRestrictionsForm, GenderForm, \ 5 from management.forms import CellRestrictionsForm, GenderForm, \
6 AttributeValuesForm, BaseFormLabelForm, CSSClassForm, TemplatePreviewForm, \ 6 AttributeValuesForm, BaseFormLabelForm, CSSClassForm, TemplatePreviewForm, \
7 TemplatePreviewGenderForm 7 TemplatePreviewGenderForm
8 -from dictionary.models import TableCell, TableHeader, ExportCell, Gender, \  
9 - LexemeAttributeValue  
10 -from tables.models import Variant, TableTemplate 8 +from dictionary.models import Gender, LexemeAttributeValue
  9 +from tables.models import Variant, TableTemplate, TableCell, ExportCell, \
  10 + TableHeader
11 from patterns.models import BaseFormLabel, PatternType 11 from patterns.models import BaseFormLabel, PatternType
12 12
13 13
tables/management/commands/import_template.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 import json 2 import json
3 from django.core.management.base import BaseCommand 3 from django.core.management.base import BaseCommand
4 -from dictionary.models import TableCell, \  
5 - LexemeAttributeValue, TableHeader, ExportCell, Gender  
6 -from tables.models import Variant, TableTemplate 4 +from dictionary.models import LexemeAttributeValue, Gender
  5 +from tables.models import Variant, TableTemplate, TableCell, ExportCell, \
  6 + TableHeader
7 from patterns.models import BaseFormLabel, PatternType 7 from patterns.models import BaseFormLabel, PatternType
8 8
9 9
tables/migrations/0003_exportcell_tablecell_tableheader.py 0 โ†’ 100644
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import migrations, models
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + dependencies = [
  10 + ('patterns', '0006_auto_20151213_1153'),
  11 + ('dictionary', '0016_auto_20151213_1400'),
  12 + ('tables', '0002_tabletemplate'),
  13 + ]
  14 +
  15 + state_operations = [
  16 + migrations.CreateModel(
  17 + name='ExportCell',
  18 + fields=[
  19 + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
  20 + ('prefix', models.CharField(max_length=20, blank=True)),
  21 + ('suffix', models.CharField(max_length=20, blank=True)),
  22 + ('tag_template', models.TextField()),
  23 + ('attribute_values', models.ManyToManyField(to='dictionary.LexemeAttributeValue')),
  24 + ('base_form_label', models.ForeignKey(to='patterns.BaseFormLabel')),
  25 + ('genders', models.ManyToManyField(to='dictionary.Gender')),
  26 + ('pattern_types', models.ManyToManyField(to='patterns.PatternType')),
  27 + ('table_template', models.ForeignKey(related_name='export_cells', to='tables.TableTemplate')),
  28 + ],
  29 + options={
  30 + 'abstract': False,
  31 + },
  32 + ),
  33 + migrations.CreateModel(
  34 + name='TableCell',
  35 + fields=[
  36 + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
  37 + ('prefix', models.CharField(max_length=20, blank=True)),
  38 + ('suffix', models.CharField(max_length=20, blank=True)),
  39 + ('qualifier', models.CharField(max_length=128, blank=True)),
  40 + ('row', models.IntegerField()),
  41 + ('col', models.IntegerField()),
  42 + ('rowspan', models.IntegerField()),
  43 + ('colspan', models.IntegerField()),
  44 + ('index', models.IntegerField()),
  45 + ('attribute_values', models.ManyToManyField(related_name='table_cells', to='dictionary.LexemeAttributeValue')),
  46 + ('base_form_label', models.ForeignKey(to='patterns.BaseFormLabel')),
  47 + ('genders', models.ManyToManyField(to='dictionary.Gender')),
  48 + ('marked_attribute_values', models.ManyToManyField(related_name='marked_cells', to='dictionary.LexemeAttributeValue')),
  49 + ('pattern_types', models.ManyToManyField(to='patterns.PatternType')),
  50 + ('table_template', models.ForeignKey(related_name='table_cells', to='tables.TableTemplate')),
  51 + ],
  52 + options={
  53 + 'abstract': False,
  54 + },
  55 + ),
  56 + migrations.CreateModel(
  57 + name='TableHeader',
  58 + fields=[
  59 + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
  60 + ('row', models.IntegerField()),
  61 + ('col', models.IntegerField()),
  62 + ('rowspan', models.IntegerField()),
  63 + ('colspan', models.IntegerField()),
  64 + ('label', models.CharField(max_length=64, db_column=b'nagl', blank=True)),
  65 + ('css_class', models.CharField(max_length=8, db_column=b'styl')),
  66 + ('attribute_values', models.ManyToManyField(to='dictionary.LexemeAttributeValue')),
  67 + ('genders', models.ManyToManyField(to='dictionary.Gender')),
  68 + ('pattern_types', models.ManyToManyField(to='patterns.PatternType')),
  69 + ('table_template', models.ForeignKey(related_name='headers', to='tables.TableTemplate')),
  70 + ],
  71 + ),
  72 + ]
  73 +
  74 + operations = [
  75 + migrations.SeparateDatabaseAndState(state_operations=state_operations),
  76 + ]
tables/models.py
@@ -2,11 +2,11 @@ @@ -2,11 +2,11 @@
2 from itertools import izip 2 from itertools import izip
3 3
4 from django.db.models import Model, CharField, TextField, ForeignKey, \ 4 from django.db.models import Model, CharField, TextField, ForeignKey, \
5 - ManyToManyField, BooleanField 5 + ManyToManyField, BooleanField, IntegerField
6 6
7 from dictionary.models import PartOfSpeech, LexemeAttribute, \ 7 from dictionary.models import PartOfSpeech, LexemeAttribute, \
8 - LexemeAttributeValue  
9 -from patterns.models import PatternType 8 + LexemeAttributeValue, Gender
  9 +from patterns.models import PatternType, BaseFormLabel
10 from tables.util import prepare_table 10 from tables.util import prepare_table
11 11
12 12
@@ -171,4 +171,149 @@ class TableTemplate(Model): @@ -171,4 +171,149 @@ class TableTemplate(Model):
171 if not all(cell['type'] == 'empty' for cell in row)] 171 if not all(cell['type'] == 'empty' for cell in row)]
172 172
173 def __unicode__(self): 173 def __unicode__(self):
174 - return self.name  
175 \ No newline at end of file 174 \ No newline at end of file
  175 + return self.name
  176 +
  177 +
  178 +def combine_qualifiers(lip_qualifiers, e_qualifiers):
  179 + if not lip_qualifiers:
  180 + return e_qualifiers
  181 + qualifiers = set()
  182 + for q in list(lip_qualifiers) + list(e_qualifiers):
  183 + if q.exclusion_class:
  184 + excluded = set(q.exclusion_class.qualifier_set.all())
  185 + qualifiers -= excluded
  186 + qualifiers.add(q)
  187 + return qualifiers
  188 +
  189 +
  190 +class Cell(Model):
  191 + base_form_label = ForeignKey(BaseFormLabel)
  192 + prefix = CharField(max_length=20, blank=True)
  193 + suffix = CharField(max_length=20, blank=True)
  194 +
  195 + def get_index(self):
  196 + return None
  197 +
  198 + def get_qualifier(self):
  199 + return ''
  200 +
  201 + def get_marked_attribute_values(self):
  202 + return set()
  203 +
  204 + def forms(self, base_endings=None, separator=u'', root=u'',
  205 + lip_qualifiers=None, lip_index=0, qualifiers=None,
  206 + edit_view=False, span=False, depr=None, cell_qualifier=False):
  207 + if qualifiers:
  208 + qualifiers_set = set(qualifiers)
  209 +
  210 + def filter_quals(quals):
  211 + if not qualifiers:
  212 + return set(quals)
  213 + else:
  214 + return set(quals) & qualifiers_set
  215 +
  216 + if lip_qualifiers and not edit_view:
  217 + # l_qual = filter_quals(lexeme_qualifiers)
  218 + lip_qual = filter_quals(lip_qualifiers)
  219 + else:
  220 + lip_qual = set()
  221 + endings = base_endings[self.base_form_label]
  222 + if span:
  223 + form_template = (
  224 + '<span class="root">%s</span>'
  225 + '%s<span class="ending">%s</span>')
  226 + else:
  227 + form_template = '%s%s%s'
  228 + if self.prefix and span:
  229 + form_template = '<span class="prefix">%s</span>' + form_template
  230 + else:
  231 + form_template = '%s' + form_template
  232 + if self.suffix and span:
  233 + form_template += '<span class="suffix">%s</span>'
  234 + else:
  235 + form_template += '%s'
  236 + if depr and depr in self.get_marked_attribute_values():
  237 + form_template = (
  238 + '<span class="marked-form" title="%s">%s</span>'
  239 + % (depr.display_value, form_template))
  240 + if cell_qualifier and self.get_qualifier():
  241 + form_template += (
  242 + ' <span class="cell-qualifier">%s</span>'
  243 + % self.get_qualifier())
  244 + forms = [
  245 + (
  246 + (self.get_index(), lip_index, ending.index),
  247 + (form_template % (
  248 + self.prefix, root, separator, ending.string, self.suffix)),
  249 + combine_qualifiers(
  250 + lip_qual, filter_quals(ending.qualifiers.all())),
  251 + )
  252 + for ending in endings
  253 + ]
  254 + return forms
  255 +
  256 + class Meta:
  257 + abstract = True
  258 +
  259 +
  260 +class TableCell(Cell):
  261 + table_template = ForeignKey('tables.TableTemplate', related_name='table_cells')
  262 + pattern_types = ManyToManyField(PatternType)
  263 + genders = ManyToManyField(Gender)
  264 + attribute_values = ManyToManyField(
  265 + LexemeAttributeValue, related_name='table_cells')
  266 + marked_attribute_values = ManyToManyField(
  267 + LexemeAttributeValue, related_name='marked_cells')
  268 + qualifier = CharField(max_length=128, blank=True)
  269 + row = IntegerField()
  270 + col = IntegerField()
  271 + rowspan = IntegerField()
  272 + colspan = IntegerField()
  273 + index = IntegerField()
  274 +
  275 + def get_index(self):
  276 + return self.index
  277 +
  278 + def get_qualifier(self):
  279 + return self.qualifier
  280 +
  281 + def get_marked_attribute_values(self):
  282 + return set(self.marked_attribute_values.all())
  283 +
  284 + def __unicode__(self):
  285 + return '%s:%s %s-%s-%s (%s, %s)' % (
  286 + self.table_template.variant_id, self.table_template.name,
  287 + self.prefix, self.base_form_label.symbol, self.suffix,
  288 + self.row, self.col)
  289 +
  290 +
  291 +class ExportCell(Cell):
  292 + table_template = ForeignKey('tables.TableTemplate', related_name='export_cells')
  293 + pattern_types = ManyToManyField(PatternType)
  294 + genders = ManyToManyField(Gender)
  295 + attribute_values = ManyToManyField(LexemeAttributeValue)
  296 + tag_template = TextField()
  297 +
  298 + def __unicode__(self):
  299 + return '%s:%s %s-%s-%s (%s)' % (
  300 + self.table_template.variant.id, self.table_template.name,
  301 + self.prefix, self.base_form_label.symbol, self.suffix,
  302 + self.tag_template)
  303 +
  304 +
  305 +class TableHeader(Model):
  306 + table_template = ForeignKey('tables.TableTemplate', related_name='headers')
  307 + pattern_types = ManyToManyField(PatternType)
  308 + genders = ManyToManyField(Gender)
  309 + attribute_values = ManyToManyField(LexemeAttributeValue)
  310 + row = IntegerField()
  311 + col = IntegerField()
  312 + rowspan = IntegerField()
  313 + colspan = IntegerField()
  314 + label = CharField(max_length=64, blank=True, db_column='nagl')
  315 + css_class = CharField(max_length=8, db_column='styl')
  316 +
  317 + def __unicode__(self):
  318 + return u'%s:%s %s (%s, %s)' % (
  319 + self.table_template.variant_id, self.table_template.name,
  320 + self.label, self.row, self.col)