1- # Generated by Django 5.2.9 on 2025-12-30 09:59
1+ # Generated by Django 5.2.9 on 2026-01-08 06:17
22
33import apps .tool_picker .models
44import django .core .validators
5+ import django .db .models .deletion
56import django_choices_field .fields
7+ import uuid
8+ from django .conf import settings
69from django .db import migrations , models
710
811
@@ -11,6 +14,7 @@ class Migration(migrations.Migration):
1114 initial = True
1215
1316 dependencies = [
17+ migrations .swappable_dependency (settings .AUTH_USER_MODEL ),
1418 ]
1519
1620 operations = [
@@ -22,46 +26,72 @@ class Migration(migrations.Migration):
2226 ('modified_at' , models .DateTimeField (auto_now = True )),
2327 ('name' , models .CharField (max_length = 200 )),
2428 ('description' , models .TextField ()),
29+ ('created_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_created' , to = settings .AUTH_USER_MODEL )),
30+ ('modified_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_modified' , to = settings .AUTH_USER_MODEL )),
2531 ],
2632 options = {
2733 'ordering' : ['name' ],
2834 'abstract' : False ,
2935 },
3036 ),
3137 migrations .CreateModel (
32- name = 'CheckboxOption ' ,
38+ name = 'Question ' ,
3339 fields = [
3440 ('id' , models .BigAutoField (auto_created = True , primary_key = True , serialize = False , verbose_name = 'ID' )),
3541 ('created_at' , models .DateTimeField (auto_now_add = True )),
3642 ('modified_at' , models .DateTimeField (auto_now = True )),
37- ('text' , models .CharField (max_length = 300 )),
43+ ('question_type' , django_choices_field .fields .IntegerChoicesField (choices = [(10 , 'Ordinal' ), (20 , 'Checkbox' )], choices_enum = apps .tool_picker .models .QuestionTypeEnum )),
44+ ('title' , models .CharField (max_length = 500 )),
45+ ('short_name' , models .CharField (max_length = 500 )),
46+ ('description' , models .TextField (blank = True )),
3847 ('order' , models .IntegerField (default = 0 , validators = [django .core .validators .MinValueValidator (0 )])),
48+ ('label_na' , models .TextField (blank = True , default = 'N/A' )),
49+ ('label_1' , models .TextField (blank = True , default = '1' )),
50+ ('label_2' , models .TextField (blank = True , default = '2' )),
51+ ('label_3' , models .TextField (blank = True , default = '3' )),
52+ ('label_4' , models .TextField (blank = True , default = '4' )),
53+ ('catalog' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'questions' , to = 'tool_picker.catalog' )),
54+ ('created_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_created' , to = settings .AUTH_USER_MODEL )),
55+ ('modified_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_modified' , to = settings .AUTH_USER_MODEL )),
3956 ],
4057 options = {
41- 'ordering' : ['question ' , 'order' ],
58+ 'ordering' : ['catalog ' , 'order' ],
4259 'abstract' : False ,
60+ 'unique_together' : {('catalog' , 'order' )},
4361 },
4462 ),
4563 migrations .CreateModel (
46- name = 'Question ' ,
64+ name = 'CheckboxOption ' ,
4765 fields = [
4866 ('id' , models .BigAutoField (auto_created = True , primary_key = True , serialize = False , verbose_name = 'ID' )),
4967 ('created_at' , models .DateTimeField (auto_now_add = True )),
5068 ('modified_at' , models .DateTimeField (auto_now = True )),
51- ('question_type' , django_choices_field .fields .IntegerChoicesField (choices = [(10 , 'Ordinal' ), (20 , 'Checkbox' )], choices_enum = apps .tool_picker .models .QuestionTypeEnum )),
52- ('title' , models .CharField (max_length = 500 )),
53- ('description' , models .TextField (blank = True )),
69+ ('text' , models .CharField (max_length = 300 )),
5470 ('order' , models .IntegerField (default = 0 , validators = [django .core .validators .MinValueValidator (0 )])),
55- ('label_na' , models .CharField (blank = True , default = 'N/A' , max_length = 100 )),
56- ('label_1' , models .CharField (blank = True , default = '1' , max_length = 100 )),
57- ('label_2' , models .CharField (blank = True , default = '2' , max_length = 100 )),
58- ('label_3' , models .CharField (blank = True , default = '3' , max_length = 100 )),
59- ('label_4' , models .CharField (blank = True , default = '4' , max_length = 100 )),
71+ ('created_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_created' , to = settings .AUTH_USER_MODEL )),
72+ ('modified_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_modified' , to = settings .AUTH_USER_MODEL )),
73+ ('question' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'options' , to = 'tool_picker.question' )),
6074 ],
6175 options = {
62- 'ordering' : ['catalog' , 'order' ],
76+ 'ordering' : ['question' , 'order' ],
77+ 'abstract' : False ,
78+ 'unique_together' : {('question' , 'order' )},
79+ },
80+ ),
81+ migrations .CreateModel (
82+ name = 'CheckboxQuestionProxy' ,
83+ fields = [
84+ ],
85+ options = {
86+ 'verbose_name' : 'Checkbox Question (Bulk Edit)' ,
87+ 'verbose_name_plural' : 'Checkbox Questions (Bulk Edit)' ,
88+ 'ordering' : ['-id' ],
6389 'abstract' : False ,
90+ 'proxy' : True ,
91+ 'indexes' : [],
92+ 'constraints' : [],
6493 },
94+ bases = ('tool_picker.question' ,),
6595 ),
6696 migrations .CreateModel (
6797 name = 'Tool' ,
@@ -72,15 +102,32 @@ class Migration(migrations.Migration):
72102 ('name' , models .CharField (max_length = 200 )),
73103 ('tagline' , models .CharField (blank = True , max_length = 300 )),
74104 ('description' , models .TextField ()),
75- ('video_link' , models .TextField (blank = True , null = True )),
76- ('tool_link' , models .TextField (blank = True , null = True )),
77- ('logo' , models .ImageField (blank = True , null = True , upload_to = 'logs/' , verbose_name = 'Logo' )),
105+ ('video_link' , models .CharField (blank = True , null = True )),
106+ ('tool_link' , models .CharField (blank = True , null = True )),
107+ ('logo' , models .ImageField (blank = True , null = True , upload_to = 'logos/' , verbose_name = 'Logo' )),
108+ ('catalog' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'tools' , to = 'tool_picker.catalog' )),
109+ ('created_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_created' , to = settings .AUTH_USER_MODEL )),
110+ ('modified_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_modified' , to = settings .AUTH_USER_MODEL )),
78111 ],
79112 options = {
80113 'ordering' : ['catalog' , 'name' ],
81114 'abstract' : False ,
82115 },
83116 ),
117+ migrations .CreateModel (
118+ name = 'UserSubmission' ,
119+ fields = [
120+ ('id' , models .UUIDField (default = uuid .uuid4 , editable = False , primary_key = True , serialize = False )),
121+ ('created_at' , models .DateTimeField (auto_now_add = True )),
122+ ('catalog' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'submissions' , to = 'tool_picker.catalog' )),
123+ ],
124+ options = {
125+ 'verbose_name' : 'User Submission' ,
126+ 'verbose_name_plural' : 'User Submissions' ,
127+ 'ordering' : ['-created_at' ],
128+ 'abstract' : False ,
129+ },
130+ ),
84131 migrations .CreateModel (
85132 name = 'ToolAnswer' ,
86133 fields = [
@@ -89,12 +136,52 @@ class Migration(migrations.Migration):
89136 ('modified_at' , models .DateTimeField (auto_now = True )),
90137 ('description' , models .TextField ()),
91138 ('ordinal_value' , django_choices_field .fields .IntegerChoicesField (blank = True , choices = [(10 , 'n/a' ), (11 , '1' ), (12 , '2' ), (13 , '3' ), (14 , '4' )], choices_enum = apps .tool_picker .models .OrdinalTypeEnum , null = True )),
139+ ('created_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_created' , to = settings .AUTH_USER_MODEL )),
140+ ('modified_by' , models .ForeignKey (on_delete = django .db .models .deletion .PROTECT , related_name = '%(class)s_modified' , to = settings .AUTH_USER_MODEL )),
141+ ('question' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'tool_answers' , to = 'tool_picker.question' )),
142+ ('selected_options' , models .ManyToManyField (blank = True , related_name = 'tool_answers' , to = 'tool_picker.checkboxoption' )),
143+ ('tool' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'answers' , to = 'tool_picker.tool' )),
92144 ],
93145 options = {
94146 'verbose_name' : 'Tool Answer' ,
95147 'verbose_name_plural' : 'Tool Answers' ,
96148 'ordering' : ['-id' ],
97149 'abstract' : False ,
150+ 'unique_together' : {('tool' , 'question' )},
151+ },
152+ ),
153+ migrations .CreateModel (
154+ name = 'UserAnswer' ,
155+ fields = [
156+ ('id' , models .BigAutoField (auto_created = True , primary_key = True , serialize = False , verbose_name = 'ID' )),
157+ ('ordinal_value' , django_choices_field .fields .IntegerChoicesField (blank = True , choices = [(10 , 'n/a' ), (11 , '1' ), (12 , '2' ), (13 , '3' ), (14 , '4' )], choices_enum = apps .tool_picker .models .OrdinalTypeEnum , null = True )),
158+ ('question' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'user_answers' , to = 'tool_picker.question' )),
159+ ('selected_options' , models .ManyToManyField (blank = True , related_name = 'user_answers' , to = 'tool_picker.checkboxoption' )),
160+ ('submission' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'answers' , to = 'tool_picker.usersubmission' )),
161+ ],
162+ options = {
163+ 'verbose_name' : 'User Answer' ,
164+ 'verbose_name_plural' : 'User Answers' ,
165+ 'ordering' : ['question__order' ],
166+ 'abstract' : False ,
167+ 'unique_together' : {('submission' , 'question' )},
168+ },
169+ ),
170+ migrations .CreateModel (
171+ name = 'RecommendationResult' ,
172+ fields = [
173+ ('id' , models .BigAutoField (auto_created = True , primary_key = True , serialize = False , verbose_name = 'ID' )),
174+ ('rank' , models .IntegerField (validators = [django .core .validators .MinValueValidator (1 ), django .core .validators .MaxValueValidator (5 )])),
175+ ('score' , models .FloatField (help_text = 'Proximity score - lower is better (closer match)' )),
176+ ('tool' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'recommendations' , to = 'tool_picker.tool' )),
177+ ('submission' , models .ForeignKey (on_delete = django .db .models .deletion .CASCADE , related_name = 'results' , to = 'tool_picker.usersubmission' )),
178+ ],
179+ options = {
180+ 'verbose_name' : 'Recommendation Result' ,
181+ 'verbose_name_plural' : 'Recommendation Results' ,
182+ 'ordering' : ['submission' , 'rank' ],
183+ 'abstract' : False ,
184+ 'unique_together' : {('submission' , 'rank' )},
98185 },
99186 ),
100187 ]
0 commit comments