diff --git a/dictionary/ajax_lemma_view.py b/dictionary/ajax_lemma_view.py index b472270..2cdf0e5 100644 --- a/dictionary/ajax_lemma_view.py +++ b/dictionary/ajax_lemma_view.py @@ -26,8 +26,8 @@ from dictionary.models import Vocabulary, Lemma, Lemma_Status, Frame_Opinion, \ Frame_Char_Value, Message, Change, Old_Frame, \ B_Frame, Entry, \ sorted_default_frame_char_vals, XcpExample, \ - POS, get_frame_char_and_its_value, get_frame_char_by_type_and_value_pk, \ - sortFrameChars, sortArguments, sortPositions, \ + POS, connect_entries, disconnect_entries, entries_related, get_frame_char_and_its_value, \ + get_frame_char_by_type_and_value_pk, sortFrameChars, sortArguments, sortPositions, \ get_or_create_position, get_schemata_by_type, pos_compatible from dictionary.forms import AddPositionForm, FrameForm, Pos_Cat_Form, \ AddNkjpExampleForm, MessageForm, SortForm, \ @@ -781,12 +781,8 @@ def check_if_selected_and_get(lemma_id, preview_lemma_id): return error, lemma, preview_lemma def are_entries_related(lemma, preview_lemma): - related = False lemma_entry, preview_lemma_entry = get_entries(lemma, preview_lemma) - if (lemma_entry.rel_entries.filter(id=preview_lemma_entry.id).exists() or - preview_lemma_entry.rel_entries.filter(id=lemma_entry.id).exists()): - related = True - return related + return entries_related(lemma_entry, preview_lemma_entry) def get_entries(lemma, preview_lemma): lemma_entry = lemma.entry_obj @@ -822,8 +818,7 @@ def check_if_has_rights_to_relate(lemma, user): def add_entries_relation(lemma, preview_lemma): lemma_entry, preview_lemma_entry = get_entries(lemma, preview_lemma) - lemma_entry.rel_entries.add(preview_lemma_entry) - preview_lemma_entry.rel_entries.add(lemma_entry) + connect_entries(lemma_entry, preview_lemma_entry) @ajax(method='post') def disrelate_entries(request, lemma_id, preview_lemma_id): @@ -850,8 +845,7 @@ def check_if_share_sematic_frames(lemma, preview_lemma): def cancel_entries_relation(request, lemma, preview_lemma): lemma_entry, preview_lemma_entry = get_entries(lemma, preview_lemma) - lemma_entry.rel_entries.remove(preview_lemma_entry) - preview_lemma_entry.rel_entries.remove(lemma_entry) + disconnect_entries(lemma_entry, preview_lemma_entry) ############################################################# @render('skladnica_examples.html') @@ -1155,11 +1149,11 @@ def need_conversion(request, from_lemma_id, to_lemma_id): def conversion_possible(from_entry, to_entry): can_be_converted = False - if (to_entry.rel_entries.filter(pk=from_entry.pk).exists() and + if (entries_related(to_entry, from_entry) and from_entry.pos.tag == 'verb' and (to_entry.pos.tag == 'noun' or to_entry.pos.tag == 'adj')): can_be_converted = True - elif (to_entry.rel_entries.filter(pk=from_entry.pk).exists() and + elif (entries_related(to_entry, from_entry) and from_entry.pos.tag == 'adj' and to_entry.pos.tag == 'noun'): can_be_converted = True return can_be_converted @@ -1637,24 +1631,17 @@ def similar_lemmas_show_synonyms(request, lemma_id): @ajax(method='post') def related_lemmas_show(request, lemma_id): - related_lemmas = [] try: lemma = Lemma.objects.get(id=lemma_id) except Lemma.DoesNotExist: raise AjaxError('main lemma not selected') - q_related_lemmas = [] - try: - entry_obj = Entry.objects.get(name=lemma.entry) - if entry_obj.rel_entries.exists(): - for related_lemma in entry_obj.rel_entries.all(): - q_related_lemmas.append(Q(entry=related_lemma.name)) - related_lemmas = Lemma.objects.filter(old=False).filter(reduce(operator.or_, q_related_lemmas)).distinct().all() - else: - related_lemmas = Lemma.objects.none() - except Entry.DoesNotExist: - pass - if len(related_lemmas) > 0: - request.session['similar_lemmas'] = related_lemmas + + related_lemmas_pks = [] + for entry in lemma.entry_obj.related_entries(): + related_lemmas_pks.append(entry.lemmas.get(old=False).pk) + + if len(related_lemmas_pks) > 0: + request.session['similar_lemmas'] = Lemma.objects.filter(pk__in=related_lemmas_pks) else: raise AjaxError('related lemmas not found') return {} diff --git a/dictionary/management/commands/add_verbs.py b/dictionary/management/commands/add_verbs.py index f9d83ee..4742835 100644 --- a/dictionary/management/commands/add_verbs.py +++ b/dictionary/management/commands/add_verbs.py @@ -6,7 +6,7 @@ import re from django.core.management.base import BaseCommand from lxml import etree -from dictionary.models import Entry, Lemma, Lemma_Status, POS, Vocabulary +from dictionary.models import Entry, Lemma, Lemma_Status, POS, Vocabulary, connect_entries VERBS_IN_DICT = 2000 POLANSKI_PATH = 'data/dictionary.xml' @@ -118,8 +118,7 @@ def add_relations_by_verb_entries(entries, relations_path, pos_tag): nverb_obj = Lemma.objects.get(old=False, entry=nverb, entry_obj__pos=pos) nverb_entry = nverb_obj.entry_obj verb_entry = verb_obj.entry_obj - verb_entry.rel_entries.add(nverb_entry) - nverb_entry.rel_entries.add(verb_entry) + connect_entries(verb_entry, nverb_entry) print line except Lemma.DoesNotExist: pass diff --git a/dictionary/management/commands/create_derivational_groups.py b/dictionary/management/commands/create_derivational_groups.py index 647ec11..366c540 100644 --- a/dictionary/management/commands/create_derivational_groups.py +++ b/dictionary/management/commands/create_derivational_groups.py @@ -2,7 +2,7 @@ from django.core.management.base import BaseCommand from dictionary.models import Entry, DerivationalGroup, connect_entries -from time import sleep + class Command(BaseCommand): @@ -10,7 +10,6 @@ class Command(BaseCommand): create_derivational_groups() - def create_derivational_groups(): for entry in Entry.objects.all(): print entry.name diff --git a/dictionary/management/commands/load_entries_relations.py b/dictionary/management/commands/load_entries_relations.py index 1d4fb4b..062c126 100644 --- a/dictionary/management/commands/load_entries_relations.py +++ b/dictionary/management/commands/load_entries_relations.py @@ -4,7 +4,7 @@ import codecs from django.core.management.base import BaseCommand -from dictionary.models import Lemma, POS, get_or_create_entry +from dictionary.models import Lemma, POS, connect_entries, get_or_create_entry NOUN_VERB_RELATIONS_PATH = 'data/nverbs/nouns/nouns+verb-freq.txt' @@ -51,8 +51,8 @@ def add_relations(entries_path, pos_tag): # val_entry = Entry(name=entry['entry'], pos=pos) # val_entry.save() verb_entry = verb_obj.entry_obj - verb_entry.rel_entries.add(nverb_entry) - nverb_entry.rel_entries.add(verb_entry) + + connect_entries(verb_entry, nverb_entry) print line except Lemma.DoesNotExist: pass @@ -81,8 +81,7 @@ def add_relations_by_nverb_entries(entries, entries_path, from_pos_tag, to_pos_t 'freq_300M': int(line_ls[2].strip())} nverb_entry = nverb_obj.entry_obj verb_entry = verb_obj.entry_obj - verb_entry.rel_entries.add(nverb_entry) - nverb_entry.rel_entries.add(verb_entry) + connect_entries(verb_entry, nverb_entry) print line except Lemma.DoesNotExist: pass diff --git a/dictionary/models.py b/dictionary/models.py index 69caac9..d3cf25e 100644 --- a/dictionary/models.py +++ b/dictionary/models.py @@ -1384,7 +1384,7 @@ class Entry(Model): related_name='+') der_group = ForeignKey('DerivationalGroup', null=True, blank=True, - related_name='powiazane') + related_name='entries') synonyms = ManyToManyField('Entry', db_table='synonimy', null=True, blank=True, related_name='rel_synonyms') @@ -1405,6 +1405,18 @@ class Entry(Model): ('view_semantics', u'Może oglądać semantykę.'), ) + def all_der_entries(self): + rel_entries = Entry.objects.none() + if self.der_group is not None: + rel_entries = self.der_group.entries.all() + return rel_entries + + def related_entries(self): + rel_entries = Entry.objects.none() + if self.der_group is not None: + rel_entries = self.der_group.entries.exclude(pk=self.pk) + return rel_entries + def related_frames(self): visible = self.visible_frames() actual = self.actual_frames() @@ -1424,8 +1436,8 @@ class Entry(Model): return get_model('semantics', 'SemanticFrame').objects.filter(pk__in=frames) def all_frames(self): - frames = self.actual_frames() - for entry in self.rel_entries.all(): + frames = get_model('semantics', 'SemanticFrame').objects.none() + for entry in self.all_der_entries(): new_frames = entry.actual_frames() frames |= new_frames return get_model('semantics', 'SemanticFrame').objects.filter(pk__in=frames) @@ -1490,7 +1502,7 @@ def connect_entries(entry1, entry2): if entry1.der_group is not None: if entry2.der_group is not None: if entry1.der_group.id != entry2.der_group.id: - entries = entry2.der_group.powiazane.all() + entries = entry2.der_group.entries.all() der_group = entry2.der_group for entry in entries: entry.der_group = entry1.der_group @@ -1511,10 +1523,14 @@ def connect_entries(entry1, entry2): entry2.save() def disconnect_entries(entry1, entry2): - if entry1.der_group.id == entry2.der_group.id: + if entries_related(entry1, entry2): entry2.der_group = None entry2.save() - + +def entries_related(entry1, entry2): + if entry1.der_group is None or entry2.der_group is None: + return False + return entry1.der_group == entry2.der_group class POS(Model): tag = CharField(max_length=16, db_column='tag', unique=True) diff --git a/dictionary/saving.py b/dictionary/saving.py index f58d5df..1fda88b 100644 --- a/dictionary/saving.py +++ b/dictionary/saving.py @@ -6,25 +6,25 @@ from semantics.models import Complement, LexicalUnitExamples from semantics.saving import modify_frames, update_meanings from wordnet.models import LexicalUnit + def get_semantic_operations(lemma, schemata_conversions): connections = [] operations = [] - frames = lemma.entry_obj.visible_frames() - for conv in schemata_conversions: - schema_operations = get_reconnect_operations_and_extend_connections(frames, + schema_operations = get_reconnect_operations_and_extend_connections(lemma, connections, conv['obj'], conv['js']) operations.extend(schema_operations) - operations.extend(get_disconnect_operations(lemma, frames, connections)) + operations.extend(get_disconnect_operations(lemma, connections)) return operations - -def get_reconnect_operations_and_extend_connections(frames, connections, schema, js_schema): + + +def get_reconnect_operations_and_extend_connections(lemma, connections, schema, js_schema): operations = [] - used_poss_ids = [] + used_poss_ids = [] for js_position in js_schema['positions']: if len(js_position['arguments']) > 0: position = get_position(schema, js_position, used_poss_ids) @@ -34,7 +34,7 @@ def get_reconnect_operations_and_extend_connections(frames, connections, schema, 'position': position, 'phrase_type': phrase_type} for conn in js_phrase_type['connections']: - operations.extend(reconnect_operations(frames, conn, new_connection_target)) + operations.extend(reconnect_operations(lemma, conn, new_connection_target)) conn_dict = next((conn_dict for conn_dict in connections if conn_dict['compl'] == conn['compl']), None) if conn_dict: @@ -44,6 +44,7 @@ def get_reconnect_operations_and_extend_connections(frames, connections, schema, 'realizations': conn['realizations']}) return operations + def get_position(schema, js_position, used_poss_ids): position = jsPosToObj(js_position) same_poss = schema.positions.filter(text_rep=position.text_rep) @@ -52,10 +53,13 @@ def get_position(schema, js_position, used_poss_ids): used_poss_ids.append(position.id) return position -def reconnect_operations(frames, connection, new_target): + +def reconnect_operations(lemma, connection, new_target): operations = [] + visible_frames = lemma.entry_obj.visible_frames() + shared_schemata_ids = get_shared_schemata_ids(lemma) compl = Complement.objects.get(id=connection['compl']) - frame = frames.get(complements=compl) + frame = visible_frames.get(complements=compl) arg_ref = create_argument_ref(frame, compl) for real_id in connection['realizations']: realization = compl.realizations.get(id=real_id) @@ -64,26 +68,31 @@ def reconnect_operations(frames, connection, new_target): new_phrase_type_ref = create_phrase_type_ref(new_target['schema'], new_target['position'], new_target['phrase_type'], realization.alternation) if new_phrase_type_ref != old_phrase_type_ref: - operations.append(create_operation('disconnect', arg_ref, old_phrase_type_ref)) + if realization.frame.id not in shared_schemata_ids: + operations.append(create_operation('disconnect', arg_ref, old_phrase_type_ref)) operations.append(create_operation('connect', arg_ref, new_phrase_type_ref)) return operations - + + def create_argument_ref(frame, complement): return 'frame_%d_comp_%d_' % (frame.id, complement.id) - + + def create_phrase_type_ref(schema, position, phrase_type, alternation): return 'schema_%d_pos_%d_arg_%d_alt_%d_' % (schema.id, position.id, phrase_type.id, alternation) + def create_operation(operation, arg_ref, phrase_type_ref): return {'operation': operation, 'arg': arg_ref, 'connect': phrase_type_ref} -def get_disconnect_operations(lemma, frames, connections): + +def get_disconnect_operations(lemma, connections): operations = [] shared_schemata_ids = get_shared_schemata_ids(lemma) - for frame in frames: + for frame in lemma.entry_obj.visible_frames(): for compl in frame.complements.all(): - conn_dict = next((conn_dict + conn_dict = next((conn_dict for conn_dict in connections if conn_dict['compl'] == compl.id), None) for real in compl.realizations.all(): if real.frame.id not in shared_schemata_ids: @@ -94,16 +103,19 @@ def get_disconnect_operations(lemma, frames, connections): operations.append(create_operation('disconnect', arg_ref, phrase_type_ref)) return operations + def get_shared_schemata_ids(lemma): ids = [f.id for f in lemma.frames.all()] - for connected in lemma.entry_obj.rel_entries.all(): + for connected in lemma.entry_obj.related_entries(): if connected.defined(): ids += [f.id for f in connected.actual_lemma().frames.all()] return ids + def update_connections(lemma_id, reconnect_operations, user): modify_frames(lemma_id, reconnect_operations, user) + def disconnect_all_examples_operations(lemma): operations = [] lex_units = lemma.entry_obj.meanings.all() @@ -116,13 +128,16 @@ def disconnect_all_examples_operations(lemma): 'example': example.id}) return operations + def connect_example_operation(example_dict, example_obj): lu = LexicalUnit.objects.get(id=example_dict['lexical_unit']) return {'operation': 'add_example', 'unit': lu.id, 'example': example_obj.id} + def disconnect_example_operation(example_dict, example_obj): lu = LexicalUnit.objects.get(id=example_dict['lexical_unit']) return {'operation': 'remove_example', 'unit': lu.id, 'example': example_obj.id} + def reconnect_examples(lemma, operations): update_meanings(lemma.id, operations) diff --git a/dictionary/validation.py b/dictionary/validation.py index 6bdea42..6d6273b 100644 --- a/dictionary/validation.py +++ b/dictionary/validation.py @@ -239,7 +239,7 @@ def get_deriv_miss_frames(lemma): def get_deriv_related_lemmas(entry): deriv_related_lemmas = [] - for rel_entry in entry.rel_entries.order_by('name'): + for rel_entry in entry.related_entries.order_by('name'): try: rel_lemma = Lemma.objects.get(entry_obj=rel_entry, old=False) deriv_related_lemmas.append(rel_lemma) diff --git a/semantics/management/commands/adjectives_todo.py b/semantics/management/commands/adjectives_todo.py index 895f4f4..ac4fd54 100644 --- a/semantics/management/commands/adjectives_todo.py +++ b/semantics/management/commands/adjectives_todo.py @@ -28,7 +28,7 @@ def adj_todo(): except ObjectDoesNotExist: continue - rel_entries = entry.rel_entries.filter(pos__tag=REL_POS) + rel_entries = entry.related_entries().filter(pos__tag=REL_POS) for rel_entry in rel_entries: if rel_entry.actual_lemma().status.status == REL_STATUS: print entry.name, ' ', entry.actual_lemma().status.status, '\t->\t', rel_entry.name, ' ', rel_entry.actual_lemma().status.status diff --git a/semantics/management/commands/nouns_semantics_todo.py b/semantics/management/commands/nouns_semantics_todo.py index 18ce3c6..790c549 100644 --- a/semantics/management/commands/nouns_semantics_todo.py +++ b/semantics/management/commands/nouns_semantics_todo.py @@ -1,14 +1,11 @@ #! /usr/bin/python # -*- coding: utf-8 -*- -import sys, os, codecs - from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist from dictionary.models import Entry, POS -from wordnet.models import LexicalUnit -from settings import PROJECT_PATH + class Command(BaseCommand): args = 'none' @@ -17,6 +14,7 @@ class Command(BaseCommand): def handle(self, **options): nouns_todo() + def nouns_todo(): noun = POS.objects.get(tag='noun') verb = POS.objects.get(tag='verb') @@ -27,7 +25,7 @@ def nouns_todo(): except ObjectDoesNotExist: continue if entry.actual_lemma().status.priority == 40: - rel_entries = entry.rel_entries.filter(pos=verb) + rel_entries = entry.related_entries().filter(pos=verb) for rel_entry in rel_entries: try: temp = entry.actual_lemma() @@ -35,4 +33,3 @@ def nouns_todo(): continue if rel_entry.actual_lemma().status.priority >= 90: print entry.name, ' ', entry.actual_lemma().status.status, '\t->\t', rel_entry.name, ' ', rel_entry.actual_lemma().status.status - diff --git a/semantics/management/commands/nouns_syntax_todo.py b/semantics/management/commands/nouns_syntax_todo.py index 667d7fc..743a336 100644 --- a/semantics/management/commands/nouns_syntax_todo.py +++ b/semantics/management/commands/nouns_syntax_todo.py @@ -1,14 +1,11 @@ #! /usr/bin/python # -*- coding: utf-8 -*- -import sys, os, codecs - from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist from dictionary.models import Entry, POS -from wordnet.models import LexicalUnit -from settings import PROJECT_PATH + class Command(BaseCommand): args = 'none' @@ -17,6 +14,7 @@ class Command(BaseCommand): def handle(self, **options): nouns_todo() + def nouns_todo(): noun = POS.objects.get(tag='noun') verb = POS.objects.get(tag='verb') @@ -27,7 +25,7 @@ def nouns_todo(): except ObjectDoesNotExist: continue if entry.actual_lemma().status.priority == 10: - rel_entries = entry.rel_entries.filter(pos=verb) + rel_entries = entry.related_entries().filter(pos=verb) for rel_entry in rel_entries: try: temp = entry.actual_lemma() @@ -35,4 +33,3 @@ def nouns_todo(): continue if rel_entry.actual_lemma().status.priority >= 90: print entry.name, ' ', entry.actual_lemma().status.status, '\t->\t', rel_entry.name, ' ', rel_entry.actual_lemma().status.status - diff --git a/semantics/management/commands/nouns_todo.py b/semantics/management/commands/nouns_todo.py index cb0b821..22f5568 100644 --- a/semantics/management/commands/nouns_todo.py +++ b/semantics/management/commands/nouns_todo.py @@ -1,14 +1,11 @@ #! /usr/bin/python # -*- coding: utf-8 -*- -import sys, os, codecs - from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist from dictionary.models import Entry, POS -from wordnet.models import LexicalUnit -from settings import PROJECT_PATH + class Command(BaseCommand): args = 'none' @@ -17,6 +14,7 @@ class Command(BaseCommand): def handle(self, **options): nouns_todo() + def nouns_todo(): noun = POS.objects.get(tag='noun') entries = Entry.objects.filter(pos=noun).order_by('name') @@ -26,8 +24,7 @@ def nouns_todo(): except ObjectDoesNotExist: continue if entry.actual_lemma().status.priority == 40: - rel_entries = entry.rel_entries.all() + rel_entries = entry.related_entries().all() for rel_entry in rel_entries: if rel_entry.actual_lemma().status.priority >= 90: print entry.name, ' ', entry.actual_lemma().status.status, '\t->\t', rel_entry.name, ' ', rel_entry.actual_lemma().status.status - diff --git a/semantics/management/commands/validate_semantics.py b/semantics/management/commands/validate_semantics.py new file mode 100644 index 0000000..192d9ec --- /dev/null +++ b/semantics/management/commands/validate_semantics.py @@ -0,0 +1,43 @@ +from django.core.management.base import BaseCommand + +from dictionary.models import Lemma +from semantics.validation import validate_schemas + + +class Command(BaseCommand): + args = 'none' + help = "" + + def handle(self, **options): + # validate_schemata() + find_related_entries_potential_errors() + + +def validate_schemata(): + lemmas = Lemma.objects.filter(old=False).order_by('entry_obj__name') + for lemma in lemmas: + if lemma.semantics_ready(): + error_msg = validate_schemas(lemma.id) + if error_msg: + print (u'%s' % lemma.entry_obj.name) + + +def find_related_entries_potential_errors(): + errors = [] + lemmas = Lemma.objects.filter(old=False).order_by('entry_obj__name') + for lemma in lemmas: + for rel_entry in lemma.entry_obj.related_entries().all(): + potential_error = u'%s <--> %s' % (lemma.entry_obj.name, rel_entry.name) + potential_error_reverse = u'%s <--> %s' % (rel_entry.name, lemma.entry_obj.name) + if (potential_error not in errors and potential_error_reverse not in errors + and has_same_schemata_in_history(lemma.entry_obj, rel_entry)): + errors.append(potential_error) + print (potential_error) + + +def has_same_schemata_in_history(entry1, entry2): + for lemma1 in entry1.lemmas.all(): + for lemma2 in entry2.lemmas.all(): + if lemma1.frames.filter(pk__in=lemma2.frames.all()).exists(): + return True + return False diff --git a/semantics/management/commands/verbs_semantics_todo.py b/semantics/management/commands/verbs_semantics_todo.py index 2a2bb06..c21d5f3 100644 --- a/semantics/management/commands/verbs_semantics_todo.py +++ b/semantics/management/commands/verbs_semantics_todo.py @@ -1,14 +1,11 @@ #! /usr/bin/python # -*- coding: utf-8 -*- -import sys, os, codecs - from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist from dictionary.models import Entry, POS -from wordnet.models import LexicalUnit -from settings import PROJECT_PATH + class Command(BaseCommand): args = 'none' @@ -17,6 +14,7 @@ class Command(BaseCommand): def handle(self, **options): nouns_todo() + def nouns_todo(): verb = POS.objects.get(tag='verb') noun = POS.objects.get(tag='noun') @@ -27,7 +25,7 @@ def nouns_todo(): except ObjectDoesNotExist: continue if entry.actual_lemma().status.priority == 40 or entry.actual_lemma().status.priority == 70: - rel_entries = entry.rel_entries.filter(pos=noun) + rel_entries = entry.related_entries().filter(pos=noun) for rel_entry in rel_entries: try: temp = rel_entry.actual_lemma() @@ -35,4 +33,3 @@ def nouns_todo(): continue if rel_entry.actual_lemma().status.priority == 40: print entry.name, ' ', entry.actual_lemma().status.status, '\t->\t', rel_entry.name, ' ', rel_entry.actual_lemma().status.status - diff --git a/semantics/views.py b/semantics/views.py index 7194861..b17cc4f 100644 --- a/semantics/views.py +++ b/semantics/views.py @@ -83,7 +83,6 @@ def ajax_frames(request, lemma_id): def create_frames_context(lemma_id, user): lemma = Lemma.objects.get(id=lemma_id) - connected = lemma.entry_obj.rel_entries.all() #lexical_units = LexicalUnit.objects.filter(Q(base__startswith=lemma.entry + u' ')|Q(base__contains=u' '+lemma.entry+u' ')|Q(base__endswith=u' '+lemma.entry)|Q(base=lemma.entry)).order_by('sense') # lexical_units = lemma.entry_obj.meanings.order_by('sense') @@ -280,7 +279,7 @@ def ajax_connected(request, lemma_id): def create_connected_context(lemma_id, user): lemma = Lemma.objects.get(id=lemma_id) - connected = lemma.entry_obj.rel_entries.all() + connected = lemma.entry_obj.related_entries().all() context = {'frames_display': [], 'connections':{'connected_reverse': [], 'connected': []}} for entry in connected: