diff --git a/.gitignore b/.gitignore index 32b5c28..50a01de 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ nosetests.xml # django ERP-specific files *.db djangoerp/settings/base.py +venv \ No newline at end of file diff --git a/README.md b/README.md index 0d402e9..b61b553 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ django ERP Pre-requisites -------------- -Make sure you have the following pre-requisites installed: +Make sure you have the following pre-requisites installed for python 2 version: * **python** >= 2.7 (required) http://www.python.org @@ -26,6 +26,8 @@ Make sure you have the following pre-requisites installed: * **mod_wsgi** (optional) http://code.google.com/p/modwsgi +Latest code is updated to use python 3. Use `pip install -r requirements.txt` to install the pre-requisites. + Installation ------------ diff --git a/djangoerp/core/management.py b/djangoerp/core/management.py index 7b78898..c1fc47b 100644 --- a/djangoerp/core/management.py +++ b/djangoerp/core/management.py @@ -15,7 +15,7 @@ __copyright__ = 'Copyright (c) 2013 Emanuele Bertoldi' __version__ = '0.0.1' -from utils.dependencies import check_dependency +from djangoerp.core.utils.dependencies import check_dependency check_dependency('django.contrib.auth') check_dependency('django.contrib.contenttypes') @@ -25,16 +25,17 @@ check_dependency('django.contrib.staticfiles') check_dependency('django.contrib.admin') check_dependency('django.contrib.admindocs') -check_dependency('django.contrib.comments') -check_dependency('django.contrib.markup') +check_dependency('django_comments') +check_dependency('django_markup') check_dependency('django.contrib.redirects') -check_dependency('django.contrib.formtools') -from django.db.models.signals import post_syncdb +from django.db.models.signals import post_migrate +from django.dispatch import receiver # Installation of application specific stuff. INSTALLING = False +@receiver(post_migrate) def install_apps(sender, **kwargs): global INSTALLING if INSTALLING: @@ -42,18 +43,18 @@ def install_apps(sender, **kwargs): INSTALLING = True - print "Installing apps ..." + print ("Installing apps ...") from django.conf import settings for app in settings.INSTALLED_APPS: if not app.startswith('django.') and (app != "djangoerp.core"): - management = __import__("%s.management" % app, {}, {}, ["install"]) try: - install_func = management.install + # Dynamically import the management module for each app + management = __import__("%s.management" % app, {}, {}, ["install"]) + install_func = getattr(management, 'install', None) + if callable(install_func): - print "Installing app %s" % app + print(f"Installing app {app}") install_func(sender, **kwargs) - except AttributeError: - pass - -post_syncdb.connect(install_apps, dispatch_uid="install_apps") + except (ImportError, AttributeError): + pass # Handle missing 'install' function or import errors gracefully diff --git a/djangoerp/core/models.py b/djangoerp/core/models.py index 7e4e16a..c2828b3 100755 --- a/djangoerp/core/models.py +++ b/djangoerp/core/models.py @@ -16,7 +16,7 @@ __version__ = '0.0.1' import json -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError def validate_json(value): diff --git a/djangoerp/core/templatetags/breadcrumbs.py b/djangoerp/core/templatetags/breadcrumbs.py index 4b7a47b..dbd6742 100644 --- a/djangoerp/core/templatetags/breadcrumbs.py +++ b/djangoerp/core/templatetags/breadcrumbs.py @@ -16,7 +16,8 @@ __version__ = '0.0.1' from django import template -from django.core.urlresolvers import reverse +# from django.core.urlresolvers import reverse # Legacy +from django.urls import reverse from django.template.loader import render_to_string from django.template import Node, NodeList, Variable, Library from django.template import TemplateSyntaxError, VariableDoesNotExist diff --git a/djangoerp/core/templatetags/modelfuncs.py b/djangoerp/core/templatetags/modelfuncs.py index 5f5f0e6..f8908fb 100644 --- a/djangoerp/core/templatetags/modelfuncs.py +++ b/djangoerp/core/templatetags/modelfuncs.py @@ -17,7 +17,7 @@ from django import template from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ register = template.Library() diff --git a/djangoerp/core/urls.py b/djangoerp/core/urls.py index 3a71d96..cfaadd7 100644 --- a/djangoerp/core/urls.py +++ b/djangoerp/core/urls.py @@ -15,9 +15,9 @@ __copyright__ = 'Copyright (c) 2013 Emanuele Bertoldi' __version__ = '0.0.1' -from django.conf.urls import patterns +from django.urls import path from django.views.generic import TemplateView -urlpatterns = patterns('', - (r'^$', TemplateView.as_view(template_name="index.html")), -) +urlpatterns = [ + path('', TemplateView.as_view(template_name="index.html"), name='home'), +] diff --git a/djangoerp/db.sqlite3 b/djangoerp/db.sqlite3 new file mode 100644 index 0000000..16c065f Binary files /dev/null and b/djangoerp/db.sqlite3 differ diff --git a/djangoerp/settings/__init__.py b/djangoerp/settings/__init__.py index 481a325..1df9e13 100644 --- a/djangoerp/settings/__init__.py +++ b/djangoerp/settings/__init__.py @@ -15,7 +15,7 @@ __copyright__ = 'Copyright (c) 2013 Emanuele Bertoldi' __version__ = '0.0.1' -from base import * +from .base import * # Auto-discovering of application specific settings. for app in INSTALLED_APPS: diff --git a/djangoerp/settings/base.py.tmpl b/djangoerp/settings/base.py.tmpl index e9f1d0f..3921428 100644 --- a/djangoerp/settings/base.py.tmpl +++ b/djangoerp/settings/base.py.tmpl @@ -18,7 +18,7 @@ __version__ = '0.0.1' import os import datetime from pytz import common_timezones -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ PROJECT_PATH = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.pardir)) THEME_PATH = os.path.join(PROJECT_PATH, 'themes', 'default') @@ -35,8 +35,8 @@ MANAGERS = ADMINS DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': '', # Or path to database file if using sqlite3. + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': os.path.join(PROJECT_PATH, 'db.sqlite3'), # Or path to database file if using sqlite3. 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. @@ -153,21 +153,44 @@ TEMPLATE_DIRS = ( # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. ) +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', # Required for admin + 'DIRS': [ + os.path.join(THEME_PATH, "templates"), + os.path.join(REPORT_PATH, "templates"), + ], + 'APP_DIRS': True, # Enable app directories for templates + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] # List of middleware classes to use. Order is important; in the request phase, # this middleware classes will be applied in the order given, and in the # response phase the middleware will be applied in reverse order. -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', # Required for session handling 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', # Required for authentication 'django.middleware.locale.LocaleMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', # Required for messages framework 'django.contrib.redirects.middleware.RedirectFallbackMiddleware', - # Uncomment the next line for simple clickjacking protection: + # Uncomment if you need clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', -) +] + # Root for URL dispatcher. ROOT_URLCONF = 'djangoerp.urls' @@ -216,10 +239,13 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.admindocs', - 'django.contrib.comments', - 'django.contrib.markup', + # 'django.contrib.comments', # Legacy + # 'django.contrib.contenttypes', # Required by django-contrib-comments + 'django_comments', + # 'django.contrib.markup', # Legacy + 'django_markup', 'django.contrib.redirects', - 'django.contrib.formtools', + # 'django.contrib.formtools', # Legacy #'south', diff --git a/djangoerp/urls.py b/djangoerp/urls.py index 82a9f48..db39f57 100755 --- a/djangoerp/urls.py +++ b/djangoerp/urls.py @@ -17,22 +17,25 @@ from django.conf.urls import * from django.conf import settings -from django.db.models.loading import cache +from django.urls import path, include +# from django.db.models.loading import cache # Legacy # Workaround for Django's ticket #10405. # See http://code.djangoproject.com/ticket/10405#comment:10 for more info. -if not cache.loaded: - cache.get_models() +# if not cache.loaded: # Legacy +# cache.get_models() # Basic URL patterns bootstrap. -urlpatterns = patterns('',) - +# urlpatterns = patterns('',) # Legacy +urlpatterns = [] if 'django.contrib.admin' in settings.INSTALLED_APPS: - from django.contrib import admin - admin.autodiscover() - urlpatterns += patterns('', (r'^admin/', include(admin.site.urls))) - if 'django.contrib.admindocs' in settings.INSTALLED_APPS: - urlpatterns += patterns('', (r'^admin/doc/', include('django.contrib.admindocs.urls'))) + from django.contrib import admin + admin.autodiscover() + urlpatterns += [path('admin/', admin.site.urls)] # Updated for Django 2.x+ + + if 'django.contrib.admindocs' in settings.INSTALLED_APPS: + urlpatterns += [path('admin/doc/', include('django.contrib.admindocs.urls'))] + if 'django.contrib.staticfiles' in settings.INSTALLED_APPS: from django.contrib.staticfiles.urls import staticfiles_urlpatterns @@ -42,37 +45,40 @@ LOADING = False def autodiscover(): - """ Auto discover urls of installed applications. - """ + """ Auto discover urls of installed applications. """ global LOADING if LOADING: return LOADING = True - import imp - + import importlib + for app in settings.INSTALLED_APPS: if app.startswith('django.'): continue - - # Step 1: find out the app's __path__. + + # Step 1: Find out the app's __path__. try: - app_path = __import__(app, {}, {}, [app.split('.')[-1]]).__path__ - except AttributeError: + app_module = importlib.import_module(app) + app_path = app_module.__path__ + except ImportError: continue - # Step 2: use imp.find_module to find the app's urls.py. + # Step 2: Check if the app has a 'urls.py'. try: - imp.find_module('urls', app_path) + importlib.import_module(f'{app}.urls') except ImportError: continue - # Step 3: return the app's url patterns. - pkg, sep, name = app.rpartition('.') - global urlpatterns - urlpatterns += patterns("", (r'^', include('%s.urls' % app))) - + # Step 3: Include the app's URL patterns. + urlpatterns.append(path(f'{app}/', include(f'{app}.urls'))) + + # Add core.urls explicitly if djangoerp.core is installed + if 'djangoerp.core' in settings.INSTALLED_APPS: + from djangoerp.core import urls as core_urls + urlpatterns.append(path('', include('djangoerp.core.urls'))) + LOADING = False autodiscover() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..50cfd06 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +asgiref==3.8.1 +bleach==6.2.0 +Django==5.1.3 +django-contrib-comments==2.2.0 +django-formtools==2.5.1 +django-markup==1.9 +docutils==0.21.2 +Markdown==3.7 +nh3==0.2.18 +Pygments==2.18.0 +python-creole==1.4.10 +pytz==2024.2 +regex==2024.11.6 +smartypants==2.0.1 +sqlparse==0.5.1 +textile==4.0.3 +typing_extensions==4.12.2 +webencodings==0.5.1