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.21";
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-GiOPIuYJAkMPW8JccJvFEoQi36rCmySHeLB7mAmg6CM=";
58 };
59
60 patches =
61 [
62 (replaceVars ./django_4_set_zoneinfo_dir.patch {
63 zoneinfo = tzdata + "/share/zoneinfo";
64 })
65 # make sure the tests don't remove packages from our pythonpath
66 # and disable failing tests
67 ./django_4_tests.patch
68
69 # fix filename length limit tests on bcachefs
70 # FIXME: remove if ever backported
71 (fetchpatch {
72 url = "https://github.com/django/django/commit/12f4f95405c7857cbf2f4bf4d0261154aac31676.patch";
73 hash = "sha256-+K20/V8sh036Ox9U7CSPgfxue7f28Sdhr3MsB7erVOk=";
74 })
75
76 # backport fix for https://code.djangoproject.com/ticket/36056
77 # FIXME: remove if ever backported upstream
78 (fetchpatch {
79 url = "https://github.com/django/django/commit/ec0e784f91b551c654f0962431cc31091926792d.patch";
80 includes = [ "django/*" ]; # tests don't apply
81 hash = "sha256-8YwdOBNJq6+GNoxzdLyN9HEEIWRXGQk9YbyfPwYVkwU=";
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 ''
94 substituteInPlace tests/utils_tests/test_autoreload.py \
95 --replace "/usr/bin/python" "${python.interpreter}"
96 ''
97 + lib.optionalString (pythonAtLeast "3.12" && stdenv.hostPlatform.system == "aarch64-linux") ''
98 # Test regression after xz was reverted from 5.6.0 to 5.4.6
99 # https://hydra.nixos.org/build/254630990
100 substituteInPlace tests/view_tests/tests/test_debug.py \
101 --replace-fail "test_files" "dont_test_files"
102 ''
103 + lib.optionalString (pythonAtLeast "3.13") ''
104 # Fixed CommandTypes.test_help_default_options_with_custom_arguments test on Python 3.13+.
105 # https://github.com/django/django/commit/3426a5c33c36266af42128ee9eca4921e68ea876
106 substituteInPlace tests/admin_scripts/tests.py --replace-fail \
107 "test_help_default_options_with_custom_arguments" \
108 "dont_test_help_default_options_with_custom_arguments"
109 '';
110
111 nativeBuildInputs = [ setuptools ];
112
113 propagatedBuildInputs = [
114 asgiref
115 sqlparse
116 ];
117
118 optional-dependencies = {
119 argon2 = [ argon2-cffi ];
120 bcrypt = [ bcrypt ];
121 };
122
123 nativeCheckInputs = [
124 # tests/requirements/py3.txt
125 aiosmtpd
126 docutils
127 geoip2
128 jinja2
129 numpy
130 pillow
131 pylibmc
132 pymemcache
133 pywatchman
134 pyyaml
135 pytz
136 redis
137 selenium
138 tblib
139 tzdata
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}