Coder Social home page Coder Social logo

django-dia's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

django-dia's Issues

Applying license

Django-dia was derived from MIT-licensed code, but didn't specify explicit license for itself. I guess the best option would be to preserve existing MIT license. Therefore I'm asking all the contributors to approve this change, namely

@encolpe
@pauloxnet
@randomfish

Thank you!

Subdirectory's application schema

I have "apps" dir for custom applications and I tried to generate schema for specified app by executing:
python manage.py make_diagram -e -o scheme apps.xparts
python manage.py make_diagram -e -o scheme xparts

and I received an error:
manage.py make_diagram: error: unrecognized arguments: xparts
or apps.xparts

Manage ForeignKey from Abstract

Hi,
I've model like this

class AbstractClass(models.Model):
    field = models.ForeignKey("related_field")

    class Meta:
        abstract = True

class RealClass(AbstractClass):

    other_field = models.CharField()`

with django 11 get_relation_target_field() in utils.py raises exception

return target_model._meta.pk
AttributeError: 'unicode' object has no attribute '_meta'

This is labelled as # 1.8 compat, so I think someting wrong in previus

# newer django
if hasattr(rel_field, 'target_field'):
    return rel_field.target_field

PS django-extensions fails too,

Error not utf-8 in comment fieldkey.

... ./django-dia/management/commands/make_diagram.py", line 64, in make_dia_attribute
value = u'#{}#'.format(value)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 9: ordinal not in range(128)

Config file for colors, styles, exclusion

Currently only model exclusion list is implemented. It is a raw text file containing list of fully qualified model names (you can see possible names via -p option). There's no way to specify background colors for apps and models, assign styles for arrows: you have to do this manually in dia and it can be very boring. Possible solution is configuration file, may be YAML, with all this data you'll fill during fune-tuning diagram output.

Automatic table layout according relevance

Current implementation places tables randomly leaving it to user to lay out manually everything in diagram. Arrows often become very long and entangled with each other.

Implementation should use something like multiple springs model: every arrow is a spring and tries to be as short as possible. That way relevant tables will be placed near each other.

python3 compatibility

Since I don't have much time right now, here is a quick patch that made django-dia work with python 3.4 for me. Most of the patch is actually pep8 reformatting that my vim does automatically, sorry for that.

Once I have a bit more time I'll explore these changes a bit further and try to create a proper pull request, but for now this might be a good starting point for anyone looking for dia-file creation from django models in python3 projects.

--- venv27_D18/lib/python2.7/site-packages/django-dia/management/commands/make_diagram.py.orig  2015-08-23 23:35:24.992012483 +0200
+++ venv34_D18/lib/python3.4/site-packages/django-dia/management/commands/make_diagram.py   2015-08-24 00:11:08.794872262 +0200
@@ -60,7 +60,7 @@
     if atype == 'boolean':
         value = 'true' if value else 'false'
     elif atype == 'string':
-        value = u'#{}#'.format(value)
+        value = '#{}#'.format(value)
         textnode = True
     elif atype == 'real':
         value = '{:.18f}'.format(value)
@@ -73,7 +73,8 @@
     elif atype == 'color':
         value = '#' + value
     elif atype == 'font':
-        attribs = {'family': unicode(value[0]), 'style': unicode(value[1]), 'name': unicode(value[2])}
+        attribs = {'family': str(value[0]), 'style': str(
+            value[1]), 'name': str(value[2])}
     else:
         raise ValueError('Unknown type')

@@ -215,14 +216,14 @@
                         pass

         xml = '<?xml version="1.0" encoding="UTF-8"?>' + \
-              ET.tostring(dom, encoding='utf-8')
+            ET.tostring(dom, encoding='unicode')

         outfile = options['outputfile']
         if outfile:
             if outfile[-4:] != '.dia':
                 outfile += '.dia'
             with gzip.open(outfile, 'wb') as f:
-                f.write(xml)
+                f.write(xml.encode('utf-8'))
         else:
             print(xml)

@@ -234,12 +235,14 @@
         rel['end_obj_id'] = end_rec['id']

         idx = None if 'start_field' not in rel or rel['start_field'].primary_key\
-                   else field_index(start_rec, rel['start_field'])
-        rel['start_port'] = allocate_free_port(start_rec) if idx is None else 12 + idx * 2
+            else field_index(start_rec, rel['start_field'])
+        rel['start_port'] = allocate_free_port(
+            start_rec) if idx is None else 12 + idx * 2

         idx = None if 'end_field' not in rel or rel['end_field'].primary_key\
-                   else field_index(end_rec, rel['end_field'])
-        rel['end_port'] = allocate_free_port(end_rec) if idx is None else 12 + idx * 2
+            else field_index(end_rec, rel['end_field'])
+        rel['end_port'] = allocate_free_port(
+            end_rec) if idx is None else 12 + idx * 2

     def xml_make_table(self, data):
         obj = ET.SubElement(self.layer, 'dia:object', attrib={
@@ -258,9 +261,12 @@
         make_dia_attribute(obj, 'underline_primary_key', 'boolean', True)
         make_dia_attribute(obj, 'bold_primary_keys', 'boolean', False)

-        make_dia_attribute(obj, 'normal_font', 'font', ('monospace', 0, 'Courier'))
-        make_dia_attribute(obj, 'name_font', 'font', ('sans', 80, 'Helvetica-Bold'))
-        make_dia_attribute(obj, 'comment_font', 'font', ('sans', 8, 'Helvetica-Oblique'))
+        make_dia_attribute(
+            obj, 'normal_font', 'font', ('monospace', 0, 'Courier'))
+        make_dia_attribute(
+            obj, 'name_font', 'font', ('sans', 80, 'Helvetica-Bold'))
+        make_dia_attribute(
+            obj, 'comment_font', 'font', ('sans', 8, 'Helvetica-Oblique'))
         make_dia_attribute(obj, 'normal_font_height', 'real', 0.8)
         make_dia_attribute(obj, 'name_font_height', 'real', 0.7)
         make_dia_attribute(obj, 'comment_font_height', 'real', 0.7)
@@ -270,12 +276,14 @@
         make_dia_attribute(obj, 'line_colour', 'color', '000000')
         make_dia_attribute(obj, 'fill_colour', 'color', data['color'])

-        attr = ET.SubElement(obj, 'dia:attribute', attrib={'name': 'attributes'})
+        attr = ET.SubElement(
+            obj, 'dia:attribute', attrib={'name': 'attributes'})
         for field in data['fields']:
             self.xml_make_field(attr, field)

     def xml_make_field(self, parent, data):
-        field = ET.SubElement(parent, 'dia:composite', attrib={'type': 'table_attribute'})
+        field = ET.SubElement(
+            parent, 'dia:composite', attrib={'type': 'table_attribute'})

         xs = (
             ('name', 'string'),
@@ -299,23 +307,29 @@
         line_style = '4' if data['dotted'] else '0'
         if self.bezier:
             make_dia_attribute(rel, 'line_style', 'enum', line_style)
-            attr = ET.SubElement(rel, 'dia:attribute', attrib={'name': 'corner_types'})
+            attr = ET.SubElement(
+                rel, 'dia:attribute', attrib={'name': 'corner_types'})
             ET.SubElement(attr, 'dia:enum', attrib={'val': '0'})
             ET.SubElement(attr, 'dia:enum', attrib={'val': '0'})
-            attr = ET.SubElement(rel, 'dia:attribute', attrib={'name': 'bez_points'})
+            attr = ET.SubElement(
+                rel, 'dia:attribute', attrib={'name': 'bez_points'})
             ET.SubElement(attr, 'dia:point', attrib={'val': '0.0,0.0'})
             ET.SubElement(attr, 'dia:point', attrib={'val': '0.0,0.0'})
             ET.SubElement(attr, 'dia:point', attrib={'val': '0.0,0.0'})
             ET.SubElement(attr, 'dia:point', attrib={'val': '0.0,0.0'})
         else:
-            attr = ET.SubElement(rel, 'dia:attribute', attrib={'name': 'line_style'})
+            attr = ET.SubElement(
+                rel, 'dia:attribute', attrib={'name': 'line_style'})
             ET.SubElement(attr, 'dia:enum', attrib={'val': line_style})
             ET.SubElement(attr, 'dia:real', attrib={'val': '1'})

-            make_dia_attribute(rel, 'start_point_desc', 'string', data['start_label'])
-            make_dia_attribute(rel, 'end_point_desc', 'string', data['end_label'])
+            make_dia_attribute(
+                rel, 'start_point_desc', 'string', data['start_label'])
+            make_dia_attribute(
+                rel, 'end_point_desc', 'string', data['end_label'])
             make_dia_attribute(rel, 'corner_radius', 'real', 0)
-            make_dia_attribute(rel, 'normal_font', 'font', ('monospace', 0, 'Courier'))
+            make_dia_attribute(
+                rel, 'normal_font', 'font', ('monospace', 0, 'Courier'))
             make_dia_attribute(rel, 'normal_font_height', 'real', 0.7)
             make_dia_attribute(rel, 'text_colour', 'color', data['color'])
             make_dia_attribute(rel, 'orth_autoroute', 'boolean', True)
@@ -324,15 +338,16 @@
         ET.SubElement(conns, 'dia:connection', attrib={
             'handle': '0',
             'to': 'O{}'.format(data['end_obj_id']),
-            'connection': unicode(data['end_port']),
+            'connection': str(data['end_port']),
         })
         ET.SubElement(conns, 'dia:connection', attrib={
             'handle': '3' if self.bezier else '1',
             'to': 'O{}'.format(data['start_obj_id']),
-            'connection': unicode(data['start_port']),
+            'connection': str(data['start_port']),
         })

-        make_dia_attribute(rel, 'end_arrow', 'enum', 3 if data['directional'] else 0)
+        make_dia_attribute(
+            rel, 'end_arrow', 'enum', 3 if data['directional'] else 0)
         make_dia_attribute(rel, 'end_arrow_length', 'real', 0.25)
         make_dia_attribute(rel, 'end_arrow_width', 'real', 0.25)
         make_dia_attribute(rel, 'line_colour', 'color', data['color'])
@@ -349,7 +364,7 @@
         for app in apps:
             result.extend(get_app_models_with_abstracts(app))
         result = list(set(result))
-        return filter(lambda model: self.get_model_name(model) not in self.exclude_fields, result)
+        return [model for model in result if self.get_model_name(model) not in self.exclude_fields]

     def prepare_field(self, field):
         return {
@@ -367,7 +382,8 @@

         fields = appmodel._meta.local_fields

-        # find primary key and print it first, ignoring implicit id if other pk exists
+        # find primary key and print it first, ignoring implicit id if other pk
+        # exists
         pk = appmodel._meta.pk
         if pk and pk in fields and not appmodel._meta.abstract:
             result.append(self.prepare_field(pk))
@@ -380,7 +396,8 @@
             result.append(self.prepare_field(field))

         if self.sort_fields:
-            result = sorted(result, key=lambda field: (not field['primary_key'], field['name']))
+            result = sorted(
+                result, key=lambda field: (not field['primary_key'], field['name']))

         return result

@@ -426,9 +443,12 @@
         abstract_fields = get_model_abstract_fields(appmodel)

         for field in appmodel._meta.local_fields:
-            if field.attname.endswith('_ptr_id'):  # excluding field redundant with inheritance relation
+            # excluding field redundant with inheritance relation
+            if field.attname.endswith('_ptr_id'):
                 continue
-            if field in abstract_fields:  # excluding fields inherited from abstract classes. they too show as local_fields
+            # excluding fields inherited from abstract classes. they too show
+            # as local_fields
+            if field in abstract_fields:
                 continue
             if self.get_field_name(field) in self.exclude_fields:
                 continue
@@ -442,10 +462,11 @@
                 continue
             if isinstance(field, ManyToManyField):
                 if (getattr(field, 'creates_table', False) or  # django 1.1.
-                   (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)):  # django 1.2
+                        (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)):  # django 1.2
                     result.append(self.prepare_relation(field, 'n', 'n'))
             elif isinstance(field, GenericRelation):
-                result.append(self.prepare_relation(field, 'n', 'n', dotted=True))
+                result.append(
+                    self.prepare_relation(field, 'n', 'n', dotted=True))

         return [rel for rel in result if rel is not None]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.