Skip to content

Commit 0e41419

Browse files
committed
fix: prepopulated fields in grappelli 2.15+
1 parent 5bbdb41 commit 0e41419

File tree

15 files changed

+1219
-109
lines changed

15 files changed

+1219
-109
lines changed

.github/workflows/test.yml

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,24 @@ jobs:
77
strategy:
88
fail-fast: false
99
matrix:
10-
python-version: ["3.7", "3.8", "3.9", "3.10"]
11-
django-version: ["2.2", "3.2", "4.0", "4.1"]
1210
grappelli: ["0"]
13-
exclude:
14-
- python-version: "3.7"
15-
django-version: "4.0"
16-
- python-version: "3.7"
17-
django-version: "4.1"
18-
- python-version: "3.10"
19-
django-version: "2.2"
20-
# Exclude some version combos that don't need to be tested (since
21-
# the combination of python and django versions is unlikely to
22-
# be germane to django-nested-admin)
23-
- python-version: "3.8"
24-
django-version: "3.2"
25-
- python-version: "3.8"
26-
django-version: "4.1"
27-
- python-version: "3.9"
28-
django-version: "4.0"
29-
- python-version: "3.9"
30-
django-version: "4.1"
11+
python-version: ["3.8"]
12+
django-version: ["3.2"]
3113
include:
3214
- grappelli: "0"
3315
name-suffix: ""
16+
- python-version: "3.9"
17+
django-version: "4.0"
18+
- python-version: "3.10"
19+
django-version: "4.1"
3420
- grappelli: "1"
3521
name-suffix: " + grappelli"
3622
python-version: "3.7"
37-
django-version: "2.2"
38-
# - grappelli: "1"
39-
# name-suffix: " + grappelli"
40-
# python-version: "3.10"
41-
# django-version: "3.2"
23+
django-version: "3.2"
24+
- grappelli: "1"
25+
name-suffix: " + grappelli"
26+
python-version: "3.8"
27+
django-version: "4.0"
4228

4329
runs-on: ubuntu-latest
4430
name: Django ${{ matrix.django-version }} (Python ${{ matrix.python-version }})${{ matrix.name-suffix }}

CHANGELOG.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ Changelog
33

44
**4.0.0 (unreleased)**
55

6-
* Remove python 2.x compatibility, drop support for EOL Django versions
7-
(all versions before 3.2)
6+
* Officially support Django 4.1
87
* Fixed: Django 4.1 autocomplete on newly added nested inlines by dispatching
98
native javascript CustomEvent events for ``formset:added`` and
109
``formset:removed``. Fixes `#229`_.
10+
* Fixed: prepopulated fields in django-grappelli 2.15+
11+
* Remove python 2.x compatibility, drop support for EOL Django versions
12+
(all versions before 3.2)
1113

1214
.. _#229: https://github.com/theatlantic/django-nested-admin/issues/229
1315

nested_admin/static/nested_admin/dist/nested_admin.js

Lines changed: 1106 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nested_admin/static/nested_admin/dist/nested_admin.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nested_admin/static/nested_admin/dist/nested_admin.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nested_admin/static/nested_admin/dist/nested_admin.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import $ from "jquery";
2+
3+
/**
4+
* Converts a grp.jQuery instance to a django.jQuery instance.
5+
*/
6+
function django$($sel) {
7+
if (typeof window.grp === "undefined") {
8+
return $($sel);
9+
}
10+
if (window.grp.jQuery.fn.init === $.fn.init) {
11+
return $($sel);
12+
}
13+
const $djangoSel = $($sel);
14+
if ($sel.prevObject) {
15+
$djangoSel.prevObject = django$($sel.prevObject);
16+
}
17+
return $djangoSel;
18+
}
19+
20+
export default django$;

nested_admin/static/nested_admin/src/nested-admin/jquery.djangoformset.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import DJNesting from "./utils";
55
import * as grappelli from "grappelli";
66
import grp from "grp";
77
import grp$ from "./grp$";
8-
// const grp = require('grp');
9-
// const grp$ = require('./grp$');
8+
import django$ from "./django$";
109

1110
var pluginName = "djangoFormset";
1211

@@ -416,7 +415,7 @@ class DjangoFormset {
416415
if (grappelli) {
417416
grappelli.reinitDateTimeFields(grp$($form));
418417
}
419-
DJNesting.DjangoInlines.initPrepopulatedFields($form);
418+
DJNesting.DjangoInlines.initPrepopulatedFields(django$($form));
420419
DJNesting.DjangoInlines.reinitDateTimeShortCuts();
421420
DJNesting.DjangoInlines.updateSelectFilter($form);
422421
DJNesting.initRelatedFields(this.prefix);

nested_admin/static/nested_admin/src/nested-admin/utils.js

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import $ from "jquery";
33
import "./jquery.djnutils";
44
import { createSortable, updatePositions } from "./sortable";
55
import regexQuote from "./regexquote";
6+
import django$ from "./django$";
67
import grp$ from "./grp$";
78

89
var DJNesting = typeof window.DJNesting != "undefined" ? window.DJNesting : {};
@@ -61,6 +62,9 @@ DJNesting.updateFormAttributes = function ($elem, search, replace, selector) {
6162
// update prepopulate ids for function initPrepopulatedFields
6263
$elem.find(".prepopulated_field").each(function () {
6364
var $node = grp$(this);
65+
if (typeof $node.prepopulate !== "function") {
66+
$node = django$(this);
67+
}
6468
var dependencyIds = $.makeArray($node.data("dependency_ids") || []);
6569
$node.data(
6670
"dependency_ids",
@@ -212,25 +216,82 @@ DJNesting.initAutocompleteFields = function (prefix, groupData) {
212216
});
213217
};
214218

219+
function getLevelPrefix(id) {
220+
return id
221+
.replace(/^\#?id_/, "")
222+
.split(/-(?:empty|__prefix__|\d+)-/g)
223+
.slice(0, -1)
224+
.join("-");
225+
}
226+
215227
// I very much regret that these are basically copy-pasted from django's
216228
// inlines.js, but they're hidden in closure scope so I don't have much choice.
217229
DJNesting.DjangoInlines = {
218230
initPrepopulatedFields: function (row) {
231+
const formPrefix = row.djangoFormPrefix();
232+
if (!formPrefix) return;
233+
const fields = $("#django-admin-prepopulated-fields-constants").data(
234+
"prepopulatedFields"
235+
);
236+
const fieldNames = new Set();
237+
const fieldDependencies = {};
238+
239+
if (Array.isArray(fields)) {
240+
fields.forEach(
241+
({ id, name, dependency_list, maxLength, allowUnicode }) => {
242+
fieldNames.add(name);
243+
const levelPrefix = getLevelPrefix(id);
244+
if (typeof fieldDependencies[levelPrefix] !== "object") {
245+
fieldDependencies[levelPrefix] = {};
246+
}
247+
fieldDependencies[levelPrefix][name] = {
248+
dependency_list,
249+
maxLength,
250+
allowUnicode,
251+
};
252+
}
253+
);
254+
fieldNames.forEach((name) => {
255+
row
256+
.find(`.form-row .field-${name}, .form-row.field-${name}`)
257+
.each(function () {
258+
const $el = $(this);
259+
const prefix = $el.djangoFormPrefix();
260+
if (!prefix) return;
261+
const levelPrefix = getLevelPrefix(prefix);
262+
const dep = (fieldDependencies[levelPrefix] || {})[name];
263+
if (dep) {
264+
$el.addClass("prepopulated_field");
265+
const $field = $el.is(":input") ? $el : $el.find(":input");
266+
$field.data("dependency_list", dep.dependency_list);
267+
$field.data("maxLength", dep.maxLength);
268+
$field.data("allowUnicode", dep.allowUnicode);
269+
}
270+
});
271+
});
272+
}
273+
if (formPrefix.match(/__prefix__/)) return;
219274
row.find(".prepopulated_field").each(function () {
220275
var field = $(this),
221276
input = field.is(":input") ? field : field.find(":input"),
222277
$input = grp$(input),
278+
inputFormPrefix = input.djangoFormPrefix(),
223279
dependencyList = $input.data("dependency_list") || [],
224-
formPrefix = input.djangoFormPrefix(),
225280
dependencies = [];
226-
if (!formPrefix || formPrefix.match(/__prefix__/)) {
227-
return;
281+
if (!inputFormPrefix || inputFormPrefix.match(/__prefix__/)) return;
282+
if (!dependencyList.length || !$input.prepopulate) {
283+
$input = django$(input);
284+
dependencyList = $input.data("dependency_list") || [];
228285
}
229286
$.each(dependencyList, function (i, fieldName) {
230-
dependencies.push("#id_" + formPrefix + fieldName);
287+
dependencies.push("#id_" + inputFormPrefix + fieldName);
231288
});
232289
if (dependencies.length) {
233-
$input.prepopulate(dependencies, input.attr("maxlength"));
290+
$input.prepopulate(
291+
dependencies,
292+
$input.data("maxLength") || $input.attr("maxlength"),
293+
$input.data("allowUnicode")
294+
);
234295
}
235296
});
236297
},

nested_admin/templates/nesting/admin/includes/grappelli_inline.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{% if fieldset.name %}<h4 class="djn-collapse-handler grp-collapse-handler">{{ fieldset.name }}</h4>{% endif %}
55
{% if fieldset.description %}<div class="grp-row"><p class="grp-description">{{ fieldset.description|safe }}</p></div>{% endif %}
66
{% for line in fieldset %}
7-
<div class="form-row djn-row grp-row grp-cells-{{ line.fields|length }}{% if not line.fields|length_is:"1" %} grp-cells{% else %}{% if line.errors %} grp-errors{% endif %}{% endif %}{% if not line.has_visible_field %} grp-row-hidden{% endif %}{% for field in line %} {{ field.field.name }}{% endfor %} ">
7+
<div class="form-row djn-row grp-row grp-cells-{{ line.fields|length }}{% if not line.fields|length_is:"1" %} grp-cells{% else %}{% if line.errors %} grp-errors{% endif %}{% for field in line %} {{ field.field.name }} field-{{ field.field.name }}{% endfor %}{% endif %}{% if not line.has_visible_field %} grp-row-hidden{% endif %}">
88
{% for field in line %}
99
{# <div{% if not line.fields|length_is:"1" %} class="cell {{ field.field.name }}{% if field.errors %} error{% endif %}"{% endif %}> #}
1010
<div class="field-box l-2c-fluid l-d-4{% if line.fields|length_is:"1" %}{% else %} grp-cell{% if field.field.name %} {{ field.field.name }} field-{{ field.field.name }}{% endif %}{% if field.field.errors %} grp-errors{% endif %}{% endif %}">

0 commit comments

Comments
 (0)