Merge lp:~stevanr/lava-dashboard/image-report-editor-backend into lp:lava-dashboard

Proposed by Stevan Radaković on 2013-09-02
Status: Merged
Merged at revision: 416
Proposed branch: lp:~stevanr/lava-dashboard/image-report-editor-backend
Merge into: lp:lava-dashboard
Diff against target: 456 lines (+440/-0)
2 files modified
dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py (+345/-0)
dashboard_app/models.py (+95/-0)
To merge this branch: bzr merge lp:~stevanr/lava-dashboard/image-report-editor-backend
Reviewer Review Type Date Requested Status
Antonio Terceiro 2013-09-02 Approve on 2013-09-02
Review via email: mp+183469@code.launchpad.net

Description of the change

Add models and migration file for Image report editor feature, based on this db model draft - http://people.linaro.org/~stevan.radakovic/image_report_db.png

To post a comment you must log in.
Antonio Terceiro (terceiro) wrote :

I don't see anything wrong with the code

 review approve

It would be nice to understand the proposed design, though, so that I can
better review the next merges that will come ... is there a high level
description somewhere?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py'
2--- dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py 1970-01-01 00:00:00 +0000
3+++ dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py 2013-09-02 13:57:25 +0000
4@@ -0,0 +1,345 @@
5+# -*- coding: utf-8 -*-
6+import datetime
7+from south.db import db
8+from south.v2 import SchemaMigration
9+from django.db import models
10+
11+
12+class Migration(SchemaMigration):
13+
14+ def forwards(self, orm):
15+ # Adding model 'ImageChartTestCase'
16+ db.create_table('dashboard_app_imagecharttestcase', (
17+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
18+ ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
19+ ('test_case', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestCase'])),
20+ ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
21+ ))
22+ db.send_create_signal('dashboard_app', ['ImageChartTestCase'])
23+
24+ # Adding model 'ImageReport'
25+ db.create_table('dashboard_app_imagereport', (
26+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
27+ ('name', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=1024)),
28+ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
29+ ))
30+ db.send_create_signal('dashboard_app', ['ImageReport'])
31+
32+ # Adding model 'ImageChartTestRun'
33+ db.create_table('dashboard_app_imagecharttestrun', (
34+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
35+ ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
36+ ('test_run', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestRun'])),
37+ ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
38+ ))
39+ db.send_create_signal('dashboard_app', ['ImageChartTestRun'])
40+
41+ # Adding model 'ImageReportChart'
42+ db.create_table('dashboard_app_imagereportchart', (
43+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
44+ ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
45+ ('image_report', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['dashboard_app.ImageReport'])),
46+ ('chart_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
47+ ('representation', self.gf('django.db.models.fields.CharField')(max_length=20)),
48+ ('target_goal', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=5, blank=True)),
49+ ('is_interactive', self.gf('django.db.models.fields.BooleanField')(default=False)),
50+ ('is_data_table_visible', self.gf('django.db.models.fields.BooleanField')(default=False)),
51+ ))
52+ db.send_create_signal('dashboard_app', ['ImageReportChart'])
53+
54+
55+ def backwards(self, orm):
56+ # Deleting model 'ImageChartTestCase'
57+ db.delete_table('dashboard_app_imagecharttestcase')
58+
59+ # Deleting model 'ImageReport'
60+ db.delete_table('dashboard_app_imagereport')
61+
62+ # Deleting model 'ImageChartTestRun'
63+ db.delete_table('dashboard_app_imagecharttestrun')
64+
65+ # Deleting model 'ImageReportChart'
66+ db.delete_table('dashboard_app_imagereportchart')
67+
68+
69+ models = {
70+ 'auth.group': {
71+ 'Meta': {'object_name': 'Group'},
72+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
73+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
74+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
75+ },
76+ 'auth.permission': {
77+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
78+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
79+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
80+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
81+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
82+ },
83+ 'auth.user': {
84+ 'Meta': {'object_name': 'User'},
85+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
86+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
87+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
88+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
89+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
90+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
91+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
92+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
93+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
94+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
95+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
96+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
97+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
98+ },
99+ 'contenttypes.contenttype': {
100+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
101+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
102+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
103+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
104+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
105+ },
106+ 'dashboard_app.attachment': {
107+ 'Meta': {'object_name': 'Attachment'},
108+ 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
109+ 'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
110+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
111+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
112+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
113+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
114+ 'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
115+ },
116+ 'dashboard_app.bundle': {
117+ 'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
118+ '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
119+ '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
120+ 'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
121+ 'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
122+ 'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
123+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
124+ 'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
125+ 'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
126+ 'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
127+ },
128+ 'dashboard_app.bundledeserializationerror': {
129+ 'Meta': {'object_name': 'BundleDeserializationError'},
130+ 'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
131+ 'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
132+ 'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
133+ },
134+ 'dashboard_app.bundlestream': {
135+ 'Meta': {'object_name': 'BundleStream'},
136+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
137+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
138+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
139+ 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
140+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
141+ 'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
142+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
143+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
144+ },
145+ 'dashboard_app.hardwaredevice': {
146+ 'Meta': {'object_name': 'HardwareDevice'},
147+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
148+ 'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
149+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
150+ },
151+ 'dashboard_app.image': {
152+ 'Meta': {'object_name': 'Image'},
153+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
154+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
155+ 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
156+ },
157+ 'dashboard_app.imagecharttestcase': {
158+ 'Meta': {'object_name': 'ImageChartTestCase'},
159+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
160+ 'image_chart': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageReportChart']"}),
161+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
162+ 'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']"})
163+ },
164+ 'dashboard_app.imagecharttestrun': {
165+ 'Meta': {'object_name': 'ImageChartTestRun'},
166+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
167+ 'image_chart': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageReportChart']"}),
168+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
169+ 'test_run': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRun']"})
170+ },
171+ 'dashboard_app.imagereport': {
172+ 'Meta': {'object_name': 'ImageReport'},
173+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
174+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
175+ 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
176+ },
177+ 'dashboard_app.imagereportchart': {
178+ 'Meta': {'object_name': 'ImageReportChart'},
179+ 'chart_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
180+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
181+ 'image_report': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dashboard_app.ImageReport']"}),
182+ 'is_data_table_visible': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
183+ 'is_interactive': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
184+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
185+ 'representation': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
186+ 'target_goal': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '5', 'blank': 'True'}),
187+ 'test_cases': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestCase']", 'through': "orm['dashboard_app.ImageChartTestCase']", 'symmetrical': 'False'}),
188+ 'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestRun']", 'through': "orm['dashboard_app.ImageChartTestRun']", 'symmetrical': 'False'})
189+ },
190+ 'dashboard_app.imageset': {
191+ 'Meta': {'object_name': 'ImageSet'},
192+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
193+ 'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
194+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
195+ },
196+ 'dashboard_app.launchpadbug': {
197+ 'Meta': {'object_name': 'LaunchpadBug'},
198+ 'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
199+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
200+ 'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
201+ },
202+ 'dashboard_app.namedattribute': {
203+ 'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
204+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
205+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
206+ 'name': ('django.db.models.fields.TextField', [], {}),
207+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
208+ 'value': ('django.db.models.fields.TextField', [], {})
209+ },
210+ 'dashboard_app.pmqabundlestream': {
211+ 'Meta': {'object_name': 'PMQABundleStream'},
212+ 'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
213+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
214+ },
215+ 'dashboard_app.softwarepackage': {
216+ 'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
217+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
218+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
219+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
220+ },
221+ 'dashboard_app.softwarepackagescratch': {
222+ 'Meta': {'object_name': 'SoftwarePackageScratch'},
223+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
224+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
225+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
226+ },
227+ 'dashboard_app.softwaresource': {
228+ 'Meta': {'object_name': 'SoftwareSource'},
229+ 'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
230+ 'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
231+ 'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
232+ 'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
233+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
234+ 'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
235+ },
236+ 'dashboard_app.tag': {
237+ 'Meta': {'object_name': 'Tag'},
238+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
239+ 'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
240+ },
241+ 'dashboard_app.test': {
242+ 'Meta': {'object_name': 'Test'},
243+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
244+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
245+ 'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
246+ },
247+ 'dashboard_app.testcase': {
248+ 'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
249+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
250+ 'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
251+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
252+ 'test_case_id': ('django.db.models.fields.TextField', [], {}),
253+ 'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
254+ },
255+ 'dashboard_app.testdefinition': {
256+ 'Meta': {'object_name': 'TestDefinition'},
257+ 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
258+ 'description': ('django.db.models.fields.TextField', [], {}),
259+ 'environment': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
260+ 'format': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
261+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
262+ 'location': ('django.db.models.fields.CharField', [], {'default': "'LOCAL'", 'max_length': '64'}),
263+ 'mime_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '64'}),
264+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
265+ 'target_dev_types': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
266+ 'target_os': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
267+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
268+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '256'})
269+ },
270+ 'dashboard_app.testresult': {
271+ 'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
272+ '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
273+ 'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
274+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
275+ 'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
276+ 'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
277+ 'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
278+ 'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
279+ 'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
280+ 'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
281+ 'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
282+ 'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
283+ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
284+ },
285+ 'dashboard_app.testrun': {
286+ 'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
287+ 'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
288+ 'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
289+ 'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
290+ 'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
291+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
292+ 'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
293+ 'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
294+ 'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
295+ 'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
296+ 'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
297+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
298+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
299+ 'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
300+ },
301+ 'dashboard_app.testrundenormalization': {
302+ 'Meta': {'object_name': 'TestRunDenormalization'},
303+ 'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
304+ 'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
305+ 'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
306+ 'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
307+ 'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
308+ },
309+ 'dashboard_app.testrunfilter': {
310+ 'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
311+ 'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
312+ 'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
313+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
314+ 'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
315+ 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
316+ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
317+ 'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
318+ },
319+ 'dashboard_app.testrunfilterattribute': {
320+ 'Meta': {'object_name': 'TestRunFilterAttribute'},
321+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
322+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
323+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
324+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
325+ },
326+ 'dashboard_app.testrunfiltersubscription': {
327+ 'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
328+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
329+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
330+ 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
331+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
332+ },
333+ 'dashboard_app.testrunfiltertest': {
334+ 'Meta': {'object_name': 'TestRunFilterTest'},
335+ 'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
336+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
337+ 'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
338+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
339+ },
340+ 'dashboard_app.testrunfiltertestcase': {
341+ 'Meta': {'object_name': 'TestRunFilterTestCase'},
342+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
343+ 'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
344+ 'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
345+ 'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
346+ }
347+ }
348+
349+ complete_apps = ['dashboard_app']
350\ No newline at end of file
351
352=== modified file 'dashboard_app/models.py'
353--- dashboard_app/models.py 2013-04-01 08:50:05 +0000
354+++ dashboard_app/models.py 2013-09-02 13:57:25 +0000
355@@ -1523,6 +1523,101 @@
356 return self.name
357
358
359+class ImageReport(models.Model):
360+
361+ name = models.SlugField(max_length=1024, unique=True)
362+
363+ description = models.TextField(blank=True, null=True)
364+
365+ def __unicode__(self):
366+ return self.name
367+
368+
369+# Chart types
370+CHART_TYPES = ((r'pass/fail', 'Pass/Fail'),
371+ (r'measurement', 'Measurement'))
372+# Chart representation
373+REPRESENTATION_TYPES = ((r'lines', 'Lines'),
374+ (r'bars', 'Bars'))
375+
376+
377+class ImageReportChart(models.Model):
378+
379+ name = models.CharField(max_length=100)
380+
381+ image_report = models.ForeignKey(
382+ ImageReport,
383+ default=None,
384+ null=False,
385+ on_delete=models.CASCADE)
386+
387+ test_runs = models.ManyToManyField(
388+ TestRun,
389+ through='ImageChartTestRun')
390+
391+ test_cases = models.ManyToManyField(
392+ TestCase,
393+ through='ImageChartTestCase')
394+
395+ chart_type = models.CharField(
396+ max_length=20,
397+ choices=CHART_TYPES,
398+ verbose_name='Chart type')
399+
400+ representation = models.CharField(
401+ max_length=20,
402+ choices=REPRESENTATION_TYPES,
403+ verbose_name='Representation type')
404+
405+ target_goal = models.DecimalField(
406+ blank = True,
407+ decimal_places = 5,
408+ max_digits = 10,
409+ null = True,
410+ verbose_name = 'Target goal')
411+
412+ is_interactive = models.BooleanField(
413+ default=False,
414+ verbose_name='Chart is interactive')
415+
416+ is_data_table_visible = models.BooleanField(
417+ default=False,
418+ verbose_name='Data table is visible')
419+
420+ def __unicode__(self):
421+ return self.name
422+
423+
424+class ImageChartTestRun(models.Model):
425+
426+ image_chart = models.ForeignKey(
427+ ImageReportChart,
428+ null=False,
429+ on_delete=models.CASCADE)
430+
431+ test_run = models.ForeignKey(
432+ TestRun,
433+ null=False,
434+ on_delete=models.CASCADE)
435+
436+ name = models.CharField(max_length=200)
437+
438+
439+class ImageChartTestCase(models.Model):
440+
441+ image_chart = models.ForeignKey(
442+ ImageReportChart,
443+ null=False,
444+ on_delete=models.CASCADE)
445+
446+ test_case = models.ForeignKey(
447+ TestCase,
448+ null=False,
449+ on_delete=models.CASCADE)
450+
451+ name = models.CharField(max_length=200)
452+
453+
454 class LaunchpadBug(models.Model):
455
456 bug_id = models.PositiveIntegerField(unique=True)

Subscribers

People subscribed via source and target branches