add user friendly json editor to django admin - django

I have a django app, using also rest_framework, and a model Product with field of type JSONField. so data is stored as JSON in Postgres, Now I want to provide the admin with a nice user friendly way on how he can change the json field (names/keys and values). is there an extension for that or is there a faster way on how to do that.
here is the column definition in the database.
my_column = JSONField(default={"editorial1": "text 1", "editorial_2": "text2", "editorial_3": "text"})
BOTH KEYS AND VALUES SHOULD BE EDITABLE BY THE ADMIN
The admin should not know anything about JSON, and should not enter/edit any json format field

You can use prettyjson's PrettyJSONWidget:
class ProductModelForm(forms.ModelForm):
class Meta:
fields = (
...
'my_column',
)
widgets = {
'my_column': PrettyJSONWidget(),
}

I ended up using the django-admin-json-editor. Not the best thing in the world, but it does the trick
https://github.com/abogushov/django-admin-json-editor

You can try https://github.com/jrief/django-entangled
In comparison to the editors mentioned above, it doesn't replace the widget used to render the JSON, but allows to override the ModelForm which otherwise is generated by Django's ModelAdmin.

Related

Where is ID saved in django ModelAdmin autocomplete_fields?

I am rewriting some administration interface to django 2.2, currently using django autocomplete_fields admin feature. Simply said I have ModelAdmin object OrderAdmin, which has nested TabularInline ProductAdmin: variable-length table of products which might be added to order. Each of these ProductAdmin holders just contains ForeignKey to actual product class, with some other attributes.
Now I wonder: where does django store id - ForeignKey - of item selected with autocomplete field? It doesn't mark OPTION in selectbox as selected, and although there is suspicious hidden input field with #cashregisterproduct_set-0-id on page, it doesn't have any value. Or is there some special way how to access it? I was thinking about adding id to __str__ method of model and parsing, but thats just ugly.
Thanks for tip.
EDIT: to make it 100% clear, where from does django get ForeignKey of object selected through autoselect_field, when creating new object from ModelAdmin?
I got misguided thinking that this is managed by django. Selected data might be accessed by using select2 framework:
selected_value = $('.myselectbox').select2().val();
related: https://stackoverflow.com/a/47451658/16268461

Fetch external data and populate form in django admin

In short:
I would like to fill in some form fields in django admin, before I click the save button, based on the input in another field.
The longer version:
I have 2 models, SteamGame and GameInfo which has a ForeignKey to SteamGame. The SteamGame table gets filled once a day with all the games listed on Steam, by fetching and parsing http://api.steampowered.com/ISteamApps/GetAppList/v0002/, the GameInfo table gets filled manually using the admin site. When adding to GameInfo I select the game from SteamGame. Some of the fields are for info I add myself, some of the fields I want to be populated after selecting the game and fetching https://store.steampowered.com/api/appdetails?appids=GAMEID&l=en for that information.
Are there some magic Django functions I can use to accomplish this? Or any other suggestions on how to do this?
Thanks!
you can pass a javascript file and using query you can make a ajax call and append the values to the form using jquery .
class HistoryConfigurationAdmin(admin.ModelAdmin):
class Media:
js = ("customjs/yourjsfile.js",)
and create a yourjsfile.js in static folder of you project.note for using jquery in django admin instead of using $(document).ready we use "jq" instead of "$" symbol
You can use javascript to achieve that.
On your admin model, add this to call for a custom javascript:
class MyAdmin(admin.ModelAdmin):
class Media:
js = ('/static/js/myMagicJavascriptThatDoesAllThisStuff.js',
)
The JS will allow the user to see what will be saved BEFORE saving it.
If you want to pull the information after the save, you should override the admin save function

Django Admin Page: Help Text for Model Methods?

I have a model method in Django that I am displaying on an admin page just like I would a model field. With a field, I can just add a help_text argument to it to give a description of what the field is and what the user should put into it. However, with a model method, help_text does not work. Adding the attribute short_description changes the way the method name is displayed, which is sort of okay, but I'm looking for a way to add a few sentences of description beneath the method value that is displayed. Is there any way to do this natively, or would I have to resort to overriding admin templates or something? (Which I do not think is worth it for something this minor).
You can do this using JS.
Replace ID-OF-THE-FIELD with the actual id of the desired field.
(function($) {
var myField = $('#ID-OF-THE-FIELD');
// find the id of the desired field by doing
// Right-Click > Inspect element
var help = $('<p class="help">A very long help text</p>');
help.insertAfter(myField);
})(django.jQuery);
Put this code into a JS file and supply this file using class Media of your ModelAdmin class.

I need to intercept data before it is put into the model from the database and vice versa

The data stored in the database is HTML. I cannot change this fact, but I want to hide it in my django admin site.
Before the database populates the model, I'd like to capture it and convert the html entities to unicode. When the model is saved to the database I'd like to reverse the process.
I can do the actual conversion from HTML entity to unicode and the other way round, but I don't know Django well enough to accomplish this.
I've looked into a modelform for the admin, but this will not work for when the data is displayed in the list_display or other places on the site.
Where/how is the best way to hook into this?
Look into making a custom field if you want it automatically to anything that calls/saves this field. Specifically, set your database-to-model conversion in to_python, and model-to-database conversion in get_prep_value.
If this is behavior specifically for one area of the admin, you could also set it all in the ModelAdmin. list_display can point to readonly fields which can do whatever it wants to the output.
Pure admin:
class ModelAdmin(admin.ModelAdmin):
list_display = ('_myfield',)
readonly_fields = ('_myfield', )
form = MyModelForm # modelform with overriden save() and init
# converting values to / from db.
def _myfield(self, obj):
return whatever_conversion_here(obj.myfield)

Pagedown(markdown editor) with Django

I trying to use the pagedown(markdown editor), the one that stackoverflow in my django based website. However to get the markdown editor in a textarea it is required to give the text area both id and class as
<textarea id="wmd-input" class="wmd-input"/>
However the form fields generated by django have a default id as id_<field-name>. Is there a way I can assign the same id to this text_area?
you can directly pass id as well in the models.py where your are passing class name. This will override the default behavior.
widgets = {
'<attribute_name>': Textarea(attrs={'class':'wmd-input','id':'wmd-input'}),
}