How to create a Django database backup? - django

I run multiple (more or less) identical Django (1.11) deployments running on the exact same schema, but different settings (I make my own Settings models). Values in these Settings models, of which there are plenty, are different for each deployment, so these sites can appear differently depending on the settings, for example.
A business requirement came up that requires me to regularly export these Settings models (DisplaySettings, CurrencySettings, etc.) from one stack, and import them into another stack. I know dumpdata and loaddata offer basic functionality in the form of JSON files, but I also need these extra functionalities from the business side:
The admin must be able to select which settings to export, including ForeignKey and ManyToManyField relations that may be in these settings.
When importing that file, the admin must be able to choose which settings in the file to import, and how (update the existing settings model, or create a new one).
The same exported file can be re-imported into the same stack to create duplicate copies of these settings.
Here are the solutions I have tried so far:
dumpdata/loaddata: Does not need the "choose which settings to import/export" requirement.
django-import-export: only supports exporting of tabular structures, i.e. foreign keys cannot be exported as part of a settings record.
django-easydump: completely unrelated package that uploads the dump to s3. Can specify which models to include, but not the attributes in each model to include.
Writing custom nested ModelSerializers in djangorestframework: doable but tedious. Requires custom front-end to handle the first requirement.
My question is: is there already a built-in way to do perform imports/exports as described, or if not, are there any qualifying third-party packages, not listed above, that I have obviously missed?

There's nothing built in that will handle all of your requirements.
If the schema is the same across all your deployments the easiest thing to do would be to set up drf endpoints for each model. Unless I'm missing something they don't need to be nested.
def import_currency_settings(new=False, remove_fields=[]):
endpoint = default_domain + '/currency_settings/'
settings = requests.get(endpoint, auth=(api_user, api_pass)).json()
for setting in settings:
for field in remove_fields:
setting.pop(field, None)
if new:
CurrencySettings.objects.create(**setting)
else:
updated = setting
updated.pop('id', None)
CurrencySettings.update_or_create(
id=setting['id'],
fields=updated
)
import_currency_settings(new=True, remove_fields=['vat'])

Related

Do i need models.py even for ready made mysql databases?

I spin up a django project. Afterwards, i didn't write models.py but instead I created a database from MySQL command line(independent from django) and created three tables with required columns. Finally i connected my django app with that database successfully. I applied migrations. But now i am confused do i need to write models.py with every field name as in column?
I remember implementing a basic project in which i did write models.py and created database using "python manage.py shell" and then put values using
"from polls.models import Choice, Question"? How do i put data now initially and then using python on some action from UI?
Do i need models.py even for ready made mysql databases?
You do not need to construct models. Some (small) webservers are even completely stateless, and thus do not use a database. But a large part of how Django can help you is based on models.
You can write your own queries, forms, etc. But often by using a ModelForm, Django can for example remove a large amount of boilerplate code. It will make it furthermore less likely that there are mistakes in your code. So although not strictly necessary, the models are usually a keystone in how Django can help you.
You can use the inspectdb [Django-doc] command to inspect the database, and let Django "sketch" the models for you. Usually you will have still some work. Since Django can, for example, not derive that a field is an EmailField, since both a CharField and EmailField look exactly the same at the database side.
You do not need to use inspectdb however. You can construct your own models. If you create your own models, but these exist already at the database side, you might want to set managed = False [Django-doc] in the Meta of your model, to prevent Django from constructing migrations.

How to load django app models in a project without this project taking responsibility for migrations

Given the following architecture of django projects apps and database schemas:
There is a django app which I want to share between several django projects.
Each project has it's own postgresql schema in behind. All schemas live in the same postgresql database.
One project is owner of the apps data, this project is responsible to run migrations and the data should live in its schema.
All other projects may access the data from the other projects schema, because they have a proper postgresql search path set.
We already use this concept with an app that has all models set to unmanaged, which works. But database changes always needs to be done manually. I'd like to benefit from django migrations and therefore I want my models either managed or unmanaged.
Do you think app config is good place to change the models meta? Any other suggestions and approaches on how to solve the requirement are also welcome.
The in the comments mentioned setting MIGRATION_MODULES works very well. In those projects which should only access the data and which should not be responsible for the migrations you can easily disable the migrations like that:
MIGRATION_MODULES = {
'yoursharedapp': None
}
Note that you need to configure the postgresql role used in the those projects with proper grants and search path.

Adding permissions to Django model without table

I'm working on some Django Rest Framework based project (quite expected API for some web-app). It has as traditional Django models, and some kind of model-like objects: they behave like Django models but don't store anything in DB. No tables, no content-types. When we ask them for objects, they goes to external API and forms resulting Queryset.
Now I need to build some role-based access system. To make the architecture clear and extensible, I want to make groups and permissions managable through the Django Admin interface. So, I guess, we need to put some permissions to DB and then we'll be able to add these permissions to user groups. After that, we'll check these permissions in DRF.permissions class. But since we have neither tables, nor content-types for these 'models', we can't add records to permissions table right now.
What is the right way to make this possible? Should I rebuild these 'models' through the metaclass with proxy = True? Or should I add a proxy layer above? Maybe I should add some dummy content-types by hand?

How to implement settings in admin?

I have Django project with my own app. This app has only two models. I need configure some options specific for this app, but in default Django admin panel.
I was thinking to create a model for example: SettingsApp and create one entry with my settings, but in admin panel, user can be add other entries or delete existing entry and app will not work. How to do it?
You should take a look at:
https://github.com/jqb/django-settings
and check if it fits well for you.
This work for my settings model:
class SettingsAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
def has_remove_permission(self, request):
return False
I recommend you to take a look at application django-livesettings from here. As said in documentation:
Django-Livesettings is a project split from the Satchmo Project. It
provides the ability to configure settings via an admin interface,
rather than by editing settings.py. In addition, livesettings allows
you to set sane defaults so that your site can be perfectly functional
without any changes. Livesettings uses caching to make sure this has
minimal impact on your site’s performance.
Finally, if you wish to lock down your site and disable the settings,
you can export your livesettings and store them in your settings.py.
This allows you have flexibility in deciding how various users
interact with your app.
Livesettings supports several types of input choices:
Boolean
Decimal
Duration
Float
Integer
Positive Integer
String
Long string
Multiple strings
Long multiple strings
Module values
Password
Livesettings has been used for many years in the satchmo project and
is considered stable and production ready.

Where is recommended spot for storing admin customizations for Django contrib apps?

I want to add Django Sessions to my Django Admin, and I am following an SO post about this, but it is unclear where I store this code. Do I put it in an admin.py file? Under what directory?
In short, it doesn't matter. You can put the code into any of your apps' admin.py files. However, in situations like these I tend to use a generic app in my project, usually named something like utils, that exists for the sole purpose of housing code that doesn't belong to one specific app or could be used by multiple apps.
If you want to be more specific, you can create a sessions app in your project specifically devoted to this code and any other code related to session management for your project, or perhaps an existing app that is somewhat related. For example, I put customizations to the User admin in my accounts app that holds the UserProfile model.