Redefine class/model of python module - python

I want to use django-achievements (link) module in my app, but it lack some fields in it's model. For example, I want to add CharField to it with path to picture of the badge/achievement. Also I will need to modify module's engine.py file for that.
What is the right way to do that? Download that module to my main app' folder and modify original files, or i can somehow redefine some methods/classes of original models.py and engine.py locally without modifing original files?

I'd say fork it and make your own modifications directly to the source. If it's an improvement you can create a Pull Request and contribute your code to the actual repository (not required, you can always just keep it for your own use).

Related

Fetching subclasses that are not present in current context

The primary problem I'm trying to solve is how to detect all the subclasses of a particular class. The reason I'm unable to use __subclasses__ is that the child classes aren't yet accessible in the context from which I'm attempting to access them.
The folder structure I'm working with looks like this:
main.py
projects/
__init__.py
project.py
some_project_child.py
What I'd like to do is get a list of all subclasses of Project (defined in project.py) from main.py.
I'm able to do this by doing:
from projects.project import Project
from projects.some_project_child import SomeProjectChild
Project.__subclasses__
The aspect of this approach I'd like to avoid is having to add an import line every time I add a new project file/class. I realize I can do this by iterating over the files in the directory and import each one's contents but is there a cleaner more pythonic manner of handling this?
It is the nature of a non-compiled language like Python that it is impossible to do anything like this without importing. There is simply no way for Python to know what subclasses any class has without executing the files they are defined in.

Make global variables available in multiple modules

I am creating an application consisting of several modules. There is one main.py file which will be the file to run the application. The main.py file will load the configuration file(s) and put them in the 'config'-variable. It will also import the application-module-file (the file which holds the source-code of the application itself, a.k.a. application-class) and start the instance.
I am not very experienced in coding Python, and my biggest question is if I am doing it the right way, by using a main-file to handle all needed stuff (loading configuration-files for example). The problem I am having right now is that I cannot access the 'config'-variable that was defined in the main.py-file from any other module and/or Python-file.
Is it possible to make a global variable for configuration-values exc.? I know in PHP I used to create a singleton object which holds all the specific global arguments. I could also create a global 'ROOT'-variable to hold the full path to the root of the application, which is needed to load/import new files, this is also not possible in Python as far as I know.
I hope someone can help me out of this or send me in the right direction so I can continue working on this project.
The answer seems to be by Matthias:
Use from AppName.modules import settings and then access the data in the module with settings.value. According to PEP-8, the style guide for Python code, wildcard imports should be avoided and would in fact lead to undesirable behaviour in this case.
Thanks you all for the help!

Global includes in Django

I want to create a module containing different utility functions and classes to use across different apps. It's not going to define any models or views. What's the best way to do this?
I would delete django-specific files like models.py, forms.py, and views.py, unless you intend to use them for their standard purpose.
From there create whatever files you want to house your custom functions/classes. I usually create an app_utils.py and put everything there. You might want to split it into separate functions.
It's really up to you. Django apps are no different from any other python package. To use methods/classes in another app you'll just use
from myapp.myapp_utils import *
Another perfectly good option is just to create a Python package yourself. All that entails is creating a directory with an __init__.py file in it.

python single configuration file

I am developing a project that requires a single configuration file whose data is used by multiple modules.
My question is: what is the common approach to that? should i read the configuration file from each
of my modules (files) or is there any other way to do it?
I was thinking to have a module named config.py that reads the configuration files and whenever I need a config I do import config and then do something like config.data['teamsdir'] get the 'teamsdir' property (for example).
response: opted for the conf.py approach then since it it is modular, flexible and simple
I can just put the configuration data directly in the file, latter if i want to read from a json file a xml file or multiple sources i just change the conf.py and make sure the data is accessed the same way.
accepted answer: chose "Alex Martelli" response because it was the most complete. voted up other answers because they where good and useful too.
I like the approach of a single config.py module whose body (when first imported) parses one or more configuration-data files and sets its own "global variables" appropriately -- though I'd favor config.teamdata over the round-about config.data['teamdata'] approach.
This assumes configuration settings are read-only once loaded (except maybe in unit-testing scenarios, where the test-code will be doing its own artificial setting of config variables to properly exercise the code-under-test) -- it basically exploits the nature of a module as the simplest Pythonic form of "singleton" (when you don't need subclassing or other features supported only by classes and not by modules, of course).
"One or more" configuration files (e.g. first one somewhere in /etc for general default settings, then one under /usr/local for site-specific overrides thereof, then again possibly one in the user's home directory for user specific settings) is a common and useful pattern.
The approach you describe is ok. If you want to add support for user config files, you can use execfile(os.path.expanduser("~/.yourprogram/config.py")).
One nice approach is to parse the config file(s) into a Python object when the application starts and pass this object around to all classes and modules requiring access to the configuration.
This may save a lot of time parsing the config.
If you want to share your config across different machines, you could perhaps put it on a web server and do import like this:
import urllib2
confstr = urllib2.urlopen("http://yourhost/config.py").read()
exec(confstr)
And if you want to share it across different languages, perhaps you can use JSON to encode and parse the configuration:
import urllib2
import simplejson
confstr = urllib2.urlopen("http://yourhost/config.py").read()
config = simplejson.loads(confstr)

Using and Installing Django Custom Field Models

I found a custom field model (JSONField) that I would like to integrate into my Django project.
Where do I actually put the JSONField.py file? -- Would it reside in my Django project or would I put it in something like: /django/db/models/fields/
Since I assume it can be done multiple ways, would it then impact how JSONField (or any custom field for that matter) would get imported into my models.py file as well?
It's worth remembering that Django is just Python, and so the same rules apply to Django customisations as they would for any other random Python library you might download. To use a bit of code, it has to be in a module somewhere on your Pythonpath, and then you can just to from foo import x.
I sometimes have a lib directory within my Django project structure, and put into it all the various things I might need to import. In this case I might put the JSONField code into a module called fields, as I might have other customised fields.
Since I know my project is already on the Pythonpath, I can just do from lib.fields import JSONField, then I can just do myfield = JSONField(options) in the model definition.
For the first question, I would rather not put it into django directory, because in case of upgrades you may end up loosing all of your changes. It is a general point: modifying an external piece of code will lead to increased maintenance costs.
Therefore, I would suggest you putting it into some place accessible from your pythonpath - it could be a module in your project, or directly inside the site-packages directory.
As about the second question, just "installing" it will not impact your existing models.
You have to explicitly use it, by either by adding it to all of your models that need it, either by defining a model that uses it, and from whom all of your models will inherit.
The best thing would be to keep Django and customizations apart. You could place the file anywhere on your pythonpath really

Categories