Login

Admin definition converter (for newforms-admin)

Author:
willhardy
Posted:
July 19, 2008
Language:
Python
Version:
.96
Score:
1 (after 1 ratings)

A script I wrote a little while ago to help speed up newforms-admin conversion.

From memory it works best when run from an old-forms installation, but it is still useful post-conversion. There are some features missing, but it's supposed to be a starter.

Just install this command and run: ./manange.py port2nfa > admin.py

(To install, copy the file to management/commands/port2nfa.py in an app somewhere)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
       Title: Port to newforms-admin
     Project: Developer tools
      Author: Will Hardy (http://willhardy.com.au)
        Date: June 2008
       Usage: ./manage.py port2nfa > admin.py

       To do: * inline classes
              * prepopulate_from

"""

import sys
from django.db import models
from django.core.management.base import BaseCommand
from django import utils
from django.contrib import admin

# Redefine repr to be able to handle proxy objects within lists, tuples and dicts
_python_repr = repr
def repr(obj):
    if isinstance(obj, list):
        return u"[%s]" % ", ".join([ repr(item) for item in obj ])
    elif isinstance(obj, tuple):
        return u"(%s, )" % ", ".join([ repr(item) for item in obj ])
    elif isinstance(obj, dict):
        items = []
        for key, value in obj.items():
            items.append(u"%s: %s" % (repr(key), repr(value)))
        return "{%s}" % ", ".join(items)
    elif obj.__class__.__name__  == "__proxy__":
        return "_(%s)" % repr(unicode(obj))
    return _python_repr(obj)


class Command(BaseCommand):
    help = 'Generates a python script to define the admin site from an oldforms admin definition..'
    args = '[appname ...]'

    def handle(self, *app_labels, **options):
        from django.db.models import get_app, get_apps, get_models

        if len(app_labels) == 0:
            app_list = get_apps()
        else:
            app_list = [get_app(app_label) for app_label in app_labels]

        # Get a list of all the relevant models
        models = []
        for app in app_list:
            models += get_models(app)

        # A dictionary to store required imports
        imports = {}

        # process the models to create a list of entries, and update the imports dictionary
        entries = get_entries(models, imports)

        # Structure the full output
        lines = Lines()
        lines += 'from django.contrib import admin'
        lines += 'from django.utils.translation import ugettext_lazy as _'
        lines += get_import_lines(imports)

        lines.add_empty_line()
        lines += entries

        lines += "site = admin.AdminSite()"
        lines += [ "site.register(%s, %sAdmin)" % (model, model) for model in imports.keys() ]

        print lines


def get_entries(models, imports):
    entries = []

    for model in models:
        entry = "\n".join(get_model_lines(model))
        if entry:
            if model.__name__ in imports:
                sys.stderr.write("A model with this name has already been processed! Skipping %s" % model.__name__)
            else:
                entries.append(entry)
                imports[model.__name__] = model.__module__

    return entries


def get_model_lines(model):
    " Returns a newforms-admin definition and registration for this model. "

    lines = Lines()
    admin_attributes = hasattr(model, "Admin") and model.Admin or model._meta.admin
    if admin_attributes:
        lines += "class %sAdmin(admin.ModelAdmin):" % model.__name__
        lines += get_basic_fields(model, admin_attributes)
        lines += get_prepopulated_fields(model)
        if len(lines) == 1:
            lines += '    pass'
        lines.add_empty_line()

    return lines


def get_basic_fields(model, admin_attributes):
    lines = Lines()

    if hasattr(model, "Admin") and model.Admin:
        for key,value in model.Admin.__dict__.items():
            if not key.startswith("__"):
                lines += "    %s = %s" % (key, repr(value))

    if model._meta.admin:
        from django.db.models.options import AdminOptions
        default_object = AdminOptions()
        for key,value in model._meta.admin.__dict__.items():
            if value and key not in ('manager', ) and value != getattr(default_object, key):
                lines += "    %s = %s" % (key, repr(value))

    return lines


def get_prepopulated_fields(model):
    fields = {}
    for field in model._meta.fields:
        if hasattr(field, 'prepopulate_from') and field.prepopulate_from:
            fields[field.name] = field.prepopulate_from
    if fields:
        return "prepopulated_fields = %s" % repr(fields)


def get_import_lines(imports):
    " Takes a dictionary of imports and formats them nicely. "

    # Create a dictionary to combine imported objects from the same module
    imports_dict = {}
    for key,value in imports.items():
        if value in imports_dict:
            imports_dict[value].append(key)
        else:
            imports_dict[value] = [key]

    # Generate the final formatted output
    return [ 'from %s import %s' % (mod, ", ".join(obj)) for mod,obj in imports_dict.items() ]



# HELPER CLASSES
################################################################################

class Lines(list):
    def add_empty_line(self):
        self.append("")

    def add_line(self, value):
        self.append(value)

    def __unicode__(self):
        return u"\n".join(self)

    def __str__(self):
        return "\n".join(self)

    def __iadd__(self, value):
        if isinstance(value, basestring):
            value = [ value ]
        if value:
            return super(Lines, self).__iadd__(value)
        else:
            return self

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.