/etc/httpd/conf/vhosts/db.tci.lan.conf
with approximately <VirtualHost *:80> ServerAdmin lufton@gmail.com ServerName www.db.tci.lan ServerAlias db.tci.lan DirectoryIndex index.html index.php DocumentRoot /home/lufton/public_html/db.tci.lan/public WSGIScriptAlias / /home/lufton/public_html/db.tci.lan/public/db/mod.wsgi Alias /js/app.js "/home/lufton/public_html/db.tci.lan/public/db/app.js" Alias /css "/home/lufton/public_html/db.tci.lan/public/db/css" <Location "/css"> SetHandler None Allow from all </Location> Alias /js "/home/lufton/public_html/db.tci.lan/public/db/js" <Location "/js"> SetHandler None Allow from all </Location> Alias /img "/home/lufton/public_html/db.tci.lan/public/db/img" <Location "/img"> SetHandler None Allow from all </Location> Alias /media "/usr/lib/python2.6/site-packages/django/contrib/admin/media" <Location "/media"> SetHandler None Allow from all </Location> <Location "/svnmanager"> SetHandler None Allow from all </Location> LogLevel warn ErrorLog /home/lufton/public_html/db.tci.lan/log/error.log CustomLog /home/lufton/public_html/db.tci.lan/log/access.log combined </VirtualHost> LoadModule python_module modules/mod_python.so <Directory /home/lufton/public_html/db.tci.lan/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all AddHandler mod_python .py PythonHandler mod_python.publisher | .py AddHandler mod_python .psp .psp_ PythonHandler mod_python.psp | .psp .psp_ PythonDebug On </Directory>
*.py
files by Python and creates 5 alias ( /js/app.js
, /img
, /css
, /js
, /media
) to serve the static ExtJS files and Django Admin. Also adds the project path to the Python system path./etc/httpd/conf/vhosts/
folder are included in the config file. To do this, add / uncomment the line in the /etc/httpd/conf/httpd.conf
file: Include /etc/httpd/conf/vhosts/*.conf
db
located along the path /srv/svn/repos/db
. After the repository is created, it is necessary to configure the SVN so that after each commit, the repository HEAD files are updated in the root folder of the server. To do this, first of all you need to checkout the repository in the root folder of the server. This is done as usual.svn checkout 127.0.0.1/svn/db /home/lufton/public_html/db.tci.lan/public/db
/srv/svn/repos/db/hooks/post-commit.tmpl
/srv/svn/repos/db/hooks/post-commit
mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
add the lines: cd /home/lufton/public_html/db.tci.lan/public/db /usr/bin/svn update # python manage.py syncdb # /etc/init.d/httpd restart
class CoolModel ( Model ): class Meta: abstract = True app_label = "db" def __init__ ( self, *args, **kwargs ): super(CoolModel, self).__init__(*args, **kwargs) self.__initial = self._dict def toDict ( self, properties = "*" ): def getValue ( field, properties = "*" ): value = getattr(self, field.name) if isinstance(field, ForeignKey): if field.name in properties: return value.toDict(properties[field.name]) elif isinstance(value, datetime.date) or isinstance(value, datetime.datetime): return value.isoformat() elif isinstance(field, CommaSeparatedIntegerField) and isinstance(value, basestring): return json.loads(value) elif isinstance(value, Decimal): return float(value) elif isinstance(field, ImageField): return value.url if value else None elif isinstance(field, NullBooleanField): return None if value not in (True, False) else 1 if value else 0 else: return value result = {} fields = {} for field in self._meta.fields: fields[field.name] = field if isinstance(field, ForeignKey): idAttr = "%s_id" % field.name result[idAttr] = getattr(self, idAttr) else: result[field.name] = getValue(field, properties) if isinstance(properties, dict): for k, v in properties.iteritems(): if hasattr(self, k): value = getattr(self, k) if isinstance(value, CoolModel): result[k] = value.toDict(v) elif value.__class__.__name__ == "RelatedManager": result[k] = toJSON(value.all(), v) elif value is None: result[k] = {} if k in fields and isinstance(fields[k], ForeignKey) else None else: result[k] = value return result @property def diff ( self ): d1 = self.__initial d2 = self._dict diffs = [(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]] return dict(diffs) @property def original ( self ): try: return self.__class__.objects.get(id = self.id) except self.__class__.DoesNotExist: return None @property def hasChanged ( self ): return bool(self.diff) @property def changedFields ( self ): return self.diff.keys() def getFieldDiff ( self, field_name ): return self.diff.get(field_name, None) def save ( self, *args, **kwargs ): super(CoolModel, self).save(*args, **kwargs) self.__initial = self._dict @property def _dict ( self ): return model_to_dict(self, fields = [field.name for field in self._meta.fields])
{ address: { country: null, state: { type: null, fullTitle: null }, district: null, city: { type: null, fullTitle: null }, streetType: null, fullAddress: null }, type: null }
urls.py
add urlpattern to urls.py: url(r'^(?P<view>[^/]*)/.*$', 'db.views.page')
page
method to the views.py
file. def page ( req, view ): models = { "countries": Country, "statetypes": StateType, "states": State, "districts": District, "cities": City, "people": Person #... } modelClass = models[view] if view in models else None if view in models: method = req.method properties = json.loads(req.GET.get("properties", "{}")) if method == "GET": id = req.GET.get("id", None) if id: return read(req, modelClass, filters = {"id": id}, properties = properties) else: query = req.GET.get("query", None) start = int(req.GET.get("start", 0)) limit = int(req.GET.get("limit", -1)) if limit < 0: limit = None f = json.loads(req.GET.get("filter", "[]")) s = json.loads(req.GET.get("sort", "[]")) q = None filters = {} for filter in f: filters[filter["property"]] = filter["value"] queryProperties = { "countries": "title__icontains", "states": "title__icontains", "districts": "title__icontains", "cities": "title__icontains", "people": ["lastName__icontains", "firstName__icontains", "middleName__icontains"] #... } if view in queryProperties and query: if isinstance(queryProperties[view], list): for p in queryProperties[view]: q |= Q(**{p: query}) if q else Q(**{p: query}) else: q |= Q(**{queryProperties[view]: query}) if q else Q(**{queryProperties[view]: query}) sorters = ["%s%s" % ("" if k == "ASC" else "-", v) for k, v in s] return read(req, modelClass, start, limit, filters, q, sorters, properties) elif method == "POST": items = json.loads(req.raw_post_data) return create(req, modelClass, items, properties) elif method == "PUT": items = json.loads(req.raw_post_data) return update(req, modelClass, items, properties) elif method == "DELETE": items = json.loads(req.raw_post_data) return delete(req, modelClass, items) elif view in globals(): if not view in ["signin"]: if not req.user.is_authenticated: return JsonResponse({ "success": False, "message": u" !" }) else: if not req.user.is_superuser: return JsonResponse({ "success": False, "message": u" !" }) return globals()[view](req) else: return JsonResponse({ "success": False, "message": u" (%s) !" % view })
models
dictionary contains the key-value of the pair, where the key is the name of the API method, the value is the class of the corresponding model. The variable queryProperties
contains the key-value of the pair, where the key is the name of the API method, the value is the field name or a list of such names (with modifications like "__in", "__gt", "__icontains", etc.). The selection will be filtered by the query parameter by the specified fields (filters will be combined with the OR operator).svn checkout db.tci.lan/svn/db ~/Projects/db
~/Projects/db
as the path (here you need to be careful not to create the folder db
in the folder ~/Projects/db
). The path to settings.py
should be ~/Projects/db/settings.py
. Add automatically created files in SVN, create CRUD, as described above.mod.wsgi
file that Apache warned us about. import os, sys sys.path.append('/home/lufton/public_html/db.tci.lan/public') sys.path.append('C:/Documents and Settings/lufton.TCI/Projects') os.environ['DJANGO_SETTINGS_MODULE'] = 'db.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
sys.path.append
used twice in order for the configuration to work on Windows, which I sometimes use.~/Projects/db
. In the Application properties, set the appFolder: 'js/app'
Now, after each posting, you ~/Projects/db/app.js
to ~/Projects/db/js/app.js
app.js
file app.js
, because we created our own alias for it and it can be excellently issued upon request to /js/app.js
.app.js
file as described aboveSource: https://habr.com/ru/post/167165/
All Articles