Repository: django/django
File: tests/gis_tests/geoapp/tests.py (Python)

Code before:
            LineString((0, 0), (1, 1), (5, 5)),
            LineString((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)),
        )
        obj = Lines.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom.tuple, geom.tuple)

    def test_multilinestring_with_linearring(self):
        geom = MultiLineString(
            LineString((0, 0), (1, 1), (5, 5)),
            LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)),
        )
        obj = Lines.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom.tuple, geom.tuple)
        self.assertEqual(obj.geom[1].__class__.__name__, "LineString")
        self.assertEqual(obj.geom[0].tuple, geom[0].tuple)
        # LinearRings are transformed to LineString.
        self.assertEqual(obj.geom[1].__class__.__name__, "LineString")
        self.assertEqual(obj.geom[1].tuple, geom[1].tuple)

    def test_multipointfield(self):
        geom = MultiPoint(Point(1, 1), Point(0, 0))
        obj = Points.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom, geom)

    def test_geometrycollectionfield(self):
        geom = GeometryCollection(
            Point(2, 2),
            LineString((0, 0), (2, 2)),
            Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))),
        )
        obj = GeometryCollections.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom, geom)


class GeoLookupTest(TestCase):
    fixtures = ["initial"]

    def test_disjoint_lookup(self):
        "Testing the `disjoint` lookup type."
        ptown = City.objects.get(name="Pueblo")
        qs1 = City.objects.filter(point__disjoint=ptown.point)
        self.assertEqual(7, qs1.count())
        qs2 = State.objects.filter(poly__disjoint=ptown.point)
        self.assertEqual(1, qs2.count())
        self.assertEqual("Kansas", qs2[0].name)

    def test_contains_contained_lookups(self):

Review comment (bug):
I'm not sure why this fails on MariaDB. Possibly [the query doesn't use the correct syntax](https://dba.stackexchange.com/questions/278787/mariadb-error-1048-geomfromtext-returning-as-null):
```
Traceback (most recent call last):
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/tests/gis_tests/geoapp/tests.py", line 301, in test_multipointfield
    obj = Points.objects.create(geom=geom)
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/query.py", line 685, in create
    obj.save(force_insert=True, using=self.db)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/base.py", line 893, in save
    self.save_base(
    ~~~~~~~~~~~~~~^
        using=using,
        ^^^^^^^^^^^^
    ...<2 lines>...
        update_fields=update_fields,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/base.py", line 985, in save_base
    updated = self._save_table(
        raw,
    ...<4 lines>...
        update_fields,
    )
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/base.py", line 1186, in _save_table
    results = self._do_insert(
        cls._base_manager, using, insert_fields, returning_fields, raw
    )
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/base.py", line 1238, in _do_insert
    return manager._insert(
           ~~~~~~~~~~~~~~~^
        [self],
        ^^^^^^^
    ...<3 lines>...
        raw=raw,
        ^^^^^^^^
    )
    ^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/query.py", line 2003, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/models/sql/compiler.py", line 1925, in execute_sql
    cursor.execute(sql, params)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/backends/utils.py", line 79, in execute
    return self._execute_with_wrappers(
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        sql, params, many=False, executor=self._execute
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/backends/utils.py", line 92, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/backends/utils.py", line 100, in _execute
    with self.db.wrap_database_errors:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/utils.py", line 94, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/backends/utils.py", line 105, in _execute
    return self.cursor.execute(sql, params)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/django/db/backends/mysql/base.py", line 78, in execute
    return self.cursor.execute(query, args)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/tests/.venv/lib/python3.14/site-packages/MySQLdb/cursors.py", line 179, in execute
    res = self._query(mogrified_query)
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/tests/.venv/lib/python3.14/site-packages/MySQLdb/cursors.py", line 331, in _query
    self._do_get_result(db)
    ~~~~~~~~~~~~~~~~~~~^^^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/tests/.venv/lib/python3.14/site-packages/MySQLdb/cursors.py", line 136, in _do_get_result
    self._result = result = self._get_result()
                            ~~~~~~~~~~~~~~~~^^
  File "/home/jenkins/workspace/pr-mariadb/database/mysql_gis/label/mariadb/python/python3.14/tests/.venv/lib/python3.14/site-packages/MySQLdb/cursors.py", line 363, in _get_result
    return self._get_db().store_result()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
django.db.utils.IntegrityError: (1048, "Column 'geom' cannot be null")
```

Code after:
        geom = MultiLineString(
            LineString((0, 0), (1, 1), (5, 5)),
            LineString((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)),
        )
        obj = Lines.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom.tuple, geom.tuple)

    def test_multilinestring_with_linearring(self):
        geom = MultiLineString(
            LineString((0, 0), (1, 1), (5, 5)),
            LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)),
        )
        obj = Lines.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom.tuple, geom.tuple)
        self.assertEqual(obj.geom[1].__class__.__name__, "LineString")
        self.assertEqual(obj.geom[0].tuple, geom[0].tuple)
        # LinearRings are transformed to LineString.
        self.assertEqual(obj.geom[1].__class__.__name__, "LineString")
        self.assertEqual(obj.geom[1].tuple, geom[1].tuple)

    @skipIf(cannot_save_multipoint, "MariaDB cannot save MultiPoint due to a bug.")
    def test_multipointfield(self):
        geom = MultiPoint(Point(1, 1), Point(0, 0))
        obj = Points.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertEqual(obj.geom, geom)

    def test_geometrycollectionfield(self):
        geom = GeometryCollection(
            Point(2, 2),
            LineString((0, 0), (2, 2)),
            Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))),
        )
        obj = GeometryCollectionModel.objects.create(geom=geom)
        obj.refresh_from_db()
        self.assertIs(obj.geom.equals(geom), True)


class GeoLookupTest(TestCase):
    fixtures = ["initial"]

    def test_disjoint_lookup(self):
        "Testing the `disjoint` lookup type."
        ptown = City.objects.get(name="Pueblo")
        qs1 = City.objects.filter(point__disjoint=ptown.point)
        self.assertEqual(7, qs1.count())
        qs2 = State.objects.filter(poly__disjoint=ptown.point)
        self.assertEqual(1, qs2.count())
        self.assertEqual("Kansas", qs2[0].name)