1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6 fetchpatch,
7 pythonAtLeast,
8 pythonOlder,
9 replaceVars,
10
11 # build
12 setuptools,
13
14 # patched in
15 geos,
16 gdal,
17 withGdal ? false,
18
19 # propagates
20 asgiref,
21 sqlparse,
22
23 # extras
24 argon2-cffi,
25 bcrypt,
26
27 # tests
28 aiosmtpd,
29 docutils,
30 geoip2,
31 jinja2,
32 numpy,
33 pillow,
34 pylibmc,
35 pymemcache,
36 python,
37 pywatchman,
38 pyyaml,
39 pytz,
40 redis,
41 selenium,
42 tblib,
43 tzdata,
44}:
45
46buildPythonPackage rec {
47 pname = "django";
48 version = "4.2.24";
49 format = "pyproject";
50
51 disabled = pythonOlder "3.8";
52
53 src = fetchFromGitHub {
54 owner = "django";
55 repo = "django";
56 rev = "refs/tags/${version}";
57 hash = "sha256-zDPK30u2QFbHCqnlTMqF1w9iN2sPDphhyKU1u+Mp5ho=";
58 };
59
60 patches = [
61 (replaceVars ./django_4_set_zoneinfo_dir.patch {
62 zoneinfo = tzdata + "/share/zoneinfo";
63 })
64 # make sure the tests don't remove packages from our pythonpath
65 # and disable failing tests
66 ./django_4_tests.patch
67
68 # fix filename length limit tests on bcachefs
69 # FIXME: remove if ever backported
70 (fetchpatch {
71 url = "https://github.com/django/django/commit/12f4f95405c7857cbf2f4bf4d0261154aac31676.patch";
72 hash = "sha256-+K20/V8sh036Ox9U7CSPgfxue7f28Sdhr3MsB7erVOk=";
73 })
74
75 # backport fix for https://code.djangoproject.com/ticket/36056
76 # FIXME: remove if ever backported upstream
77 (fetchpatch {
78 url = "https://github.com/django/django/commit/ec0e784f91b551c654f0962431cc31091926792d.patch";
79 includes = [ "django/*" ]; # tests don't apply
80 hash = "sha256-8YwdOBNJq6+GNoxzdLyN9HEEIWRXGQk9YbyfPwYVkwU=";
81 })
82
83 ]
84 ++ lib.optionals withGdal [
85 (replaceVars ./django_4_set_geos_gdal_lib.patch {
86 geos = geos;
87 gdal = gdal;
88 extension = stdenv.hostPlatform.extensions.sharedLibrary;
89 })
90 ];
91
92 postPatch = ''
93 substituteInPlace tests/utils_tests/test_autoreload.py \
94 --replace "/usr/bin/python" "${python.interpreter}"
95 ''
96 + lib.optionalString (pythonAtLeast "3.12" && stdenv.hostPlatform.system == "aarch64-linux") ''
97 # Test regression after xz was reverted from 5.6.0 to 5.4.6
98 # https://hydra.nixos.org/build/254630990
99 substituteInPlace tests/view_tests/tests/test_debug.py \
100 --replace-fail "test_files" "dont_test_files"
101 ''
102 + lib.optionalString (pythonAtLeast "3.13") ''
103 # Fixed CommandTypes.test_help_default_options_with_custom_arguments test on Python 3.13+.
104 # https://github.com/django/django/commit/3426a5c33c36266af42128ee9eca4921e68ea876
105 substituteInPlace tests/admin_scripts/tests.py --replace-fail \
106 "test_help_default_options_with_custom_arguments" \
107 "dont_test_help_default_options_with_custom_arguments"
108 '';
109
110 nativeBuildInputs = [ setuptools ];
111
112 propagatedBuildInputs = [
113 asgiref
114 sqlparse
115 ];
116
117 optional-dependencies = {
118 argon2 = [ argon2-cffi ];
119 bcrypt = [ bcrypt ];
120 };
121
122 nativeCheckInputs = [
123 # tests/requirements/py3.txt
124 aiosmtpd
125 docutils
126 geoip2
127 jinja2
128 numpy
129 pillow
130 pylibmc
131 pymemcache
132 pywatchman
133 pyyaml
134 pytz
135 redis
136 selenium
137 tblib
138 tzdata
139 ]
140 ++ lib.flatten (lib.attrValues optional-dependencies);
141
142 doCheck =
143 !stdenv.hostPlatform.isDarwin
144 # pywatchman depends on folly which does not support 32bits
145 && !stdenv.hostPlatform.is32bit;
146
147 preCheck = ''
148 # make sure the installed library gets imported
149 rm -rf django
150
151 # provide timezone data, works only on linux
152 export TZDIR=${tzdata}/${python.sitePackages}/tzdata/zoneinfo
153 '';
154
155 checkPhase = ''
156 runHook preCheck
157
158 pushd tests
159 ${python.interpreter} runtests.py --settings=test_sqlite
160 popd
161
162 runHook postCheck
163 '';
164
165 __darwinAllowLocalNetworking = true;
166
167 meta = with lib; {
168 changelog = "https://docs.djangoproject.com/en/${lib.versions.majorMinor version}/releases/${version}/";
169 description = "High-level Python Web framework that encourages rapid development and clean, pragmatic design";
170 mainProgram = "django-admin";
171 homepage = "https://www.djangoproject.com";
172 license = licenses.bsd3;
173 maintainers = with maintainers; [ hexa ];
174 };
175}