├── django_pyodbc ├── __init__.py ├── management │ ├── __init__.py │ └── commands │ │ └── __init__.py ├── metadata.py └── aggregates.py ├── tests ├── django20 │ ├── basic │ │ ├── __init__.py │ │ └── models.py │ ├── cache │ │ ├── __init__.py │ │ ├── liberal_backend.py │ │ ├── closeable_cache.py │ │ └── models.py │ ├── dates │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── defer │ │ ├── __init__.py │ │ └── models.py │ ├── delete │ │ └── __init__.py │ ├── lookup │ │ ├── __init__.py │ │ └── models.py │ ├── update │ │ ├── __init__.py │ │ └── models.py │ ├── aggregation │ │ ├── __init__.py │ │ └── models.py │ ├── backends │ │ └── __init__.py │ ├── bulk_create │ │ ├── __init__.py │ │ └── models.py │ ├── custom_pk │ │ ├── __init__.py │ │ ├── models.py │ │ └── fields.py │ ├── datatypes │ │ ├── __init__.py │ │ └── models.py │ ├── datetimes │ │ ├── __init__.py │ │ └── models.py │ ├── db_typecasts │ │ ├── models.py │ │ ├── __init__.py │ │ └── tests.py │ ├── expressions │ │ ├── __init__.py │ │ └── models.py │ ├── indexes │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── m2m_and_m2o │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── m2m_regress │ │ ├── __init__.py │ │ └── models.py │ ├── many_to_one │ │ ├── __init__.py │ │ └── models.py │ ├── null_fk │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── one_to_one │ │ ├── __init__.py │ │ └── models.py │ ├── or_lookups │ │ ├── __init__.py │ │ └── models.py │ ├── ordering │ │ ├── __init__.py │ │ └── models.py │ ├── pagination │ │ ├── __init__.py │ │ ├── models.py │ │ └── custom.py │ ├── queries │ │ └── __init__.py │ ├── raw_query │ │ ├── __init__.py │ │ ├── models.py │ │ └── fixtures │ │ │ └── raw_query_books.json │ ├── tablespaces │ │ ├── __init__.py │ │ └── models.py │ ├── timezones │ │ ├── __init__.py │ │ ├── urls.py │ │ ├── admin.py │ │ ├── forms.py │ │ ├── models.py │ │ └── fixtures │ │ │ └── tz_users.xml │ ├── commands_sql │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── custom_columns │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── custom_managers │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── custom_methods │ │ ├── __init__.py │ │ ├── tests.py │ │ └── models.py │ ├── defer_regress │ │ ├── __init__.py │ │ └── models.py │ ├── foreign_object │ │ └── __init__.py │ ├── get_or_create │ │ ├── __init__.py │ │ └── models.py │ ├── inspectdb │ │ ├── __init__.py │ │ └── models.py │ ├── introspection │ │ ├── __init__.py │ │ └── models.py │ ├── m2m_intermediary │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── m2m_multiple │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── m2m_recursive │ │ ├── __init__.py │ │ └── models.py │ ├── m2m_signals │ │ ├── __init__.py │ │ └── models.py │ ├── m2o_recursive │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── many_to_many │ │ ├── __init__.py │ │ └── models.py │ ├── many_to_one_null │ │ ├── __init__.py │ │ └── models.py │ ├── max_lengths │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── model_regress │ │ ├── __init__.py │ │ └── models.py │ ├── null_fk_ordering │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── null_queries │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── prefetch_related │ │ └── __init__.py │ ├── reserved_names │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── reverse_lookup │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── select_related │ │ ├── __init__.py │ │ └── models.py │ ├── string_lookup │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── transactions │ │ ├── __init__.py │ │ └── models.py │ ├── aggregation_regress │ │ ├── __init__.py │ │ └── models.py │ ├── delete_regress │ │ ├── __init__.py │ │ └── models.py │ ├── expressions_regress │ │ ├── __init__.py │ │ └── models.py │ ├── force_insert_update │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── generic_relations │ │ └── __init__.py │ ├── get_object_or_404 │ │ ├── __init__.py │ │ └── models.py │ ├── get_or_create_regress │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── initial_sql_regress │ │ ├── __init__.py │ │ ├── models.py │ │ ├── sql │ │ │ └── simple.sql │ │ └── tests.py │ ├── known_related_objects │ │ ├── __init__.py │ │ ├── models.py │ │ └── fixtures │ │ │ └── tournament.json │ ├── m2m_through │ │ ├── __init__.py │ │ └── models.py │ ├── many_to_one_regress │ │ ├── __init__.py │ │ └── models.py │ ├── model_inheritance │ │ └── __init__.py │ ├── multiple_database │ │ ├── __init__.py │ │ ├── fixtures │ │ │ ├── multidb-common.json │ │ │ ├── pets.json │ │ │ ├── multidb.other.json │ │ │ └── multidb.default.json │ │ └── models.py │ ├── mutually_referential │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── nested_foreign_keys │ │ ├── __init__.py │ │ └── models.py │ ├── one_to_one_regress │ │ ├── __init__.py │ │ └── models.py │ ├── order_with_respect_to │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── transactions_regress │ │ ├── __init__.py │ │ └── models.py │ ├── update_only_fields │ │ ├── __init__.py │ │ └── models.py │ ├── custom_columns_regress │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── custom_managers_regress │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── distinct_on_fields │ │ ├── __init__.py │ │ └── models.py │ ├── generic_relations_regress │ │ └── __init__.py │ ├── get_earliest_or_latest │ │ ├── __init__.py │ │ └── models.py │ ├── model_inheritance_regress │ │ └── __init__.py │ ├── reverse_single_related │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ ├── select_for_update │ │ ├── __init__.py │ │ └── models.py │ ├── select_related_onetoone │ │ ├── __init__.py │ │ └── models.py │ ├── select_related_regress │ │ ├── __init__.py │ │ └── models.py │ ├── m2m_through_regress │ │ ├── __init__.py │ │ ├── fixtures │ │ │ └── m2m_through.json │ │ └── models.py │ ├── model_inheritance_same_model_name │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py │ └── model_inheritance_select_related │ │ ├── __init__.py │ │ ├── models.py │ │ └── tests.py ├── django14 │ └── model_forms │ │ ├── test.png │ │ └── test2.png ├── test_sqlite.py └── test_django_pyodbc.py ├── .github └── CODEOWNERS ├── .gitignore ├── setup.cfg ├── bump_version.sh ├── Makefile └── setup.py /django_pyodbc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/basic/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/cache/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/dates/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/defer/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/delete/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/lookup/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/update/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/aggregation/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/backends/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/bulk_create/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/custom_pk/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/datatypes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/datetimes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/db_typecasts/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/expressions/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/indexes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_and_m2o/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/many_to_one/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/null_fk/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/one_to_one/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/or_lookups/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/ordering/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/pagination/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/queries/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/raw_query/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/tablespaces/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/timezones/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @dlo @RossRogers 2 | -------------------------------------------------------------------------------- /django_pyodbc/management/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/commands_sql/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/custom_columns/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/custom_managers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/custom_methods/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/db_typecasts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/defer_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/foreign_object/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/get_or_create/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/inspectdb/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/introspection/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_intermediary/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_multiple/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_recursive/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_signals/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/m2o_recursive/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/many_to_many/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/many_to_one_null/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/max_lengths/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/model_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/null_fk_ordering/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/null_queries/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/prefetch_related/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/reserved_names/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/reverse_lookup/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/select_related/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/string_lookup/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/transactions/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/aggregation_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/delete_regress/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/expressions_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/force_insert_update/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/generic_relations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/get_object_or_404/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/get_or_create_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/initial_sql_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/known_related_objects/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_through/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/django20/many_to_one_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/multiple_database/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/mutually_referential/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/nested_foreign_keys/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/one_to_one_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/order_with_respect_to/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/transactions_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/update_only_fields/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_pyodbc/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/django20/custom_columns_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/custom_managers_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/distinct_on_fields/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /tests/django20/generic_relations_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/get_earliest_or_latest/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/reverse_single_related/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/select_for_update/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /tests/django20/select_related_onetoone/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/select_related_regress/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/m2m_through_regress/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_same_model_name/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_select_related/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .svn/ 3 | build/ 4 | dist/ 5 | django_pyodbc.egg-info/ 6 | .eggs/ 7 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [egg_info] 2 | tag_svn_revision = false 3 | 4 | [bdist_wheel] 5 | universal=1 6 | -------------------------------------------------------------------------------- /tests/django14/model_forms/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lionheart/django-pyodbc/HEAD/tests/django14/model_forms/test.png -------------------------------------------------------------------------------- /tests/django14/model_forms/test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lionheart/django-pyodbc/HEAD/tests/django14/model_forms/test2.png -------------------------------------------------------------------------------- /tests/django20/select_for_update/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Person(models.Model): 5 | name = models.CharField(max_length=30) 6 | -------------------------------------------------------------------------------- /tests/django20/initial_sql_regress/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for initial SQL insertion. 3 | """ 4 | 5 | from django.db import models 6 | 7 | 8 | class Simple(models.Model): 9 | name = models.CharField(max_length = 50) 10 | 11 | -------------------------------------------------------------------------------- /tests/django20/commands_sql/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Comment(models.Model): 5 | pass 6 | 7 | 8 | class Book(models.Model): 9 | title = models.CharField(max_length=100, db_index=True) 10 | comments = models.ManyToManyField(Comment) 11 | -------------------------------------------------------------------------------- /bump_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" != "" ]; then 4 | sed -i "" "s/\(__version__[ ]*=\).*/\1 \"$1\"/g" django_pyodbc/metadata.py 5 | git add . 6 | git commit -m "bump version to $1" 7 | git tag $1 8 | git push origin master 9 | git push --tags 10 | make 11 | fi 12 | -------------------------------------------------------------------------------- /tests/django20/multiple_database/fixtures/multidb-common.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "multiple_database.book", 5 | "fields": { 6 | "title": "The Definitive Guide to Django", 7 | "published": "2009-7-8" 8 | } 9 | } 10 | ] -------------------------------------------------------------------------------- /tests/django20/cache/liberal_backend.py: -------------------------------------------------------------------------------- 1 | from django.core.cache.backends.locmem import LocMemCache 2 | 3 | 4 | class LiberalKeyValidationMixin(object): 5 | def validate_key(self, key): 6 | pass 7 | 8 | class CacheClass(LiberalKeyValidationMixin, LocMemCache): 9 | pass 10 | 11 | -------------------------------------------------------------------------------- /tests/django20/timezones/urls.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.conf.urls import patterns, include 4 | from django.contrib import admin 5 | 6 | from . import admin as tz_admin 7 | 8 | urlpatterns = patterns('', 9 | (r'^admin/', include(admin.site.urls)), 10 | ) 11 | -------------------------------------------------------------------------------- /tests/django20/cache/closeable_cache.py: -------------------------------------------------------------------------------- 1 | from django.core.cache.backends.locmem import LocMemCache 2 | 3 | 4 | class CloseHookMixin(object): 5 | closed = False 6 | 7 | def close(self, **kwargs): 8 | self.closed = True 9 | 10 | class CacheClass(CloseHookMixin, LocMemCache): 11 | pass 12 | -------------------------------------------------------------------------------- /tests/django20/transactions_regress/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Mod(models.Model): 5 | fld = models.IntegerField() 6 | 7 | class SubMod(Mod): 8 | cnt = models.IntegerField(unique=True) 9 | 10 | class M2mA(models.Model): 11 | others = models.ManyToManyField('M2mB') 12 | 13 | 14 | class M2mB(models.Model): 15 | fld = models.IntegerField() 16 | -------------------------------------------------------------------------------- /tests/django20/pagination/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils.encoding import python_2_unicode_compatible 3 | 4 | 5 | @python_2_unicode_compatible 6 | class Article(models.Model): 7 | headline = models.CharField(max_length=100, default='Default headline') 8 | pub_date = models.DateTimeField() 9 | 10 | def __str__(self): 11 | return self.headline 12 | -------------------------------------------------------------------------------- /tests/django20/multiple_database/fixtures/pets.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "multiple_database.pet", 5 | "fields": { 6 | "name": "Mr Bigglesworth", 7 | "owner": 1 8 | } 9 | }, 10 | { 11 | "pk": 2, 12 | "model": "multiple_database.pet", 13 | "fields": { 14 | "name": "Spot", 15 | "owner": 2 16 | } 17 | } 18 | ] -------------------------------------------------------------------------------- /tests/django20/timezones/admin.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.contrib import admin 4 | 5 | from .models import Event, Timestamp 6 | 7 | class EventAdmin(admin.ModelAdmin): 8 | list_display = ('dt',) 9 | 10 | admin.site.register(Event, EventAdmin) 11 | 12 | class TimestampAdmin(admin.ModelAdmin): 13 | readonly_fields = ('created', 'updated') 14 | 15 | admin.site.register(Timestamp, TimestampAdmin) 16 | -------------------------------------------------------------------------------- /tests/django20/cache/models.py: -------------------------------------------------------------------------------- 1 | from django.utils import timezone 2 | 3 | from django.db import models 4 | 5 | 6 | def expensive_calculation(): 7 | expensive_calculation.num_runs += 1 8 | return timezone.now() 9 | 10 | class Poll(models.Model): 11 | question = models.CharField(max_length=200) 12 | answer = models.CharField(max_length=200) 13 | pub_date = models.DateTimeField('date published', default=expensive_calculation) 14 | -------------------------------------------------------------------------------- /tests/django20/reverse_single_related/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class SourceManager(models.Manager): 5 | def get_queryset(self): 6 | return super(SourceManager, self).get_queryset().filter(is_public=True) 7 | 8 | class Source(models.Model): 9 | is_public = models.BooleanField(default=False) 10 | objects = SourceManager() 11 | 12 | class Item(models.Model): 13 | source = models.ForeignKey(Source) 14 | -------------------------------------------------------------------------------- /tests/django20/get_earliest_or_latest/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Article(models.Model): 5 | headline = models.CharField(max_length=100) 6 | pub_date = models.DateField() 7 | expire_date = models.DateField() 8 | 9 | class Meta: 10 | get_latest_by = 'pub_date' 11 | 12 | 13 | class Person(models.Model): 14 | name = models.CharField(max_length=30) 15 | birthday = models.DateField() 16 | # Note that this model doesn't have "get_latest_by" set. 17 | -------------------------------------------------------------------------------- /tests/django20/get_or_create_regress/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Publisher(models.Model): 5 | name = models.CharField(max_length=100) 6 | 7 | class Author(models.Model): 8 | name = models.CharField(max_length=100) 9 | 10 | class Book(models.Model): 11 | name = models.CharField(max_length=100) 12 | authors = models.ManyToManyField(Author, related_name='books') 13 | publisher = models.ForeignKey(Publisher, related_name='books', db_column="publisher_id_column") 14 | -------------------------------------------------------------------------------- /tests/django20/max_lengths/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class PersonWithDefaultMaxLengths(models.Model): 5 | email = models.EmailField() 6 | vcard = models.FileField(upload_to='/tmp') 7 | homepage = models.URLField() 8 | avatar = models.FilePathField() 9 | 10 | class PersonWithCustomMaxLengths(models.Model): 11 | email = models.EmailField(max_length=250) 12 | vcard = models.FileField(upload_to='/tmp', max_length=250) 13 | homepage = models.URLField(max_length=250) 14 | avatar = models.FilePathField(max_length=250) 15 | -------------------------------------------------------------------------------- /tests/django20/timezones/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from .models import Event 4 | 5 | class EventForm(forms.Form): 6 | dt = forms.DateTimeField() 7 | 8 | class EventSplitForm(forms.Form): 9 | dt = forms.SplitDateTimeField() 10 | 11 | class EventLocalizedForm(forms.Form): 12 | dt = forms.DateTimeField(localize=True) 13 | 14 | class EventModelForm(forms.ModelForm): 15 | class Meta: 16 | model = Event 17 | fields = '__all__' 18 | 19 | class EventLocalizedModelForm(forms.ModelForm): 20 | class Meta: 21 | model = Event 22 | fields = '__all__' 23 | localized_fields = '__all__' 24 | -------------------------------------------------------------------------------- /tests/django20/pagination/custom.py: -------------------------------------------------------------------------------- 1 | from django.core.paginator import Paginator, Page 2 | 3 | 4 | class ValidAdjacentNumsPage(Page): 5 | 6 | def next_page_number(self): 7 | if not self.has_next(): 8 | return None 9 | return super(ValidAdjacentNumsPage, self).next_page_number() 10 | 11 | def previous_page_number(self): 12 | if not self.has_previous(): 13 | return None 14 | return super(ValidAdjacentNumsPage, self).previous_page_number() 15 | 16 | 17 | class ValidAdjacentNumsPaginator(Paginator): 18 | 19 | def _get_page(self, *args, **kwargs): 20 | return ValidAdjacentNumsPage(*args, **kwargs) 21 | -------------------------------------------------------------------------------- /tests/django20/force_insert_update/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for forcing insert and update queries (instead of Django's normal 3 | automatic behavior). 4 | """ 5 | from django.db import models 6 | 7 | 8 | class Counter(models.Model): 9 | name = models.CharField(max_length = 10) 10 | value = models.IntegerField() 11 | 12 | class InheritedCounter(Counter): 13 | tag = models.CharField(max_length=10) 14 | 15 | class ProxyCounter(Counter): 16 | class Meta: 17 | proxy = True 18 | 19 | class SubCounter(Counter): 20 | pass 21 | 22 | class WithCustomPK(models.Model): 23 | name = models.IntegerField(primary_key=True) 24 | value = models.IntegerField() 25 | -------------------------------------------------------------------------------- /tests/django20/mutually_referential/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 24. Mutually referential many-to-one relationships 3 | 4 | Strings can be used instead of model literals to set up "lazy" relations. 5 | """ 6 | 7 | from django.db import models 8 | 9 | 10 | class Parent(models.Model): 11 | name = models.CharField(max_length=100) 12 | 13 | # Use a simple string for forward declarations. 14 | bestchild = models.ForeignKey("Child", null=True, related_name="favoured_by") 15 | 16 | class Child(models.Model): 17 | name = models.CharField(max_length=100) 18 | 19 | # You can also explicitally specify the related app. 20 | parent = models.ForeignKey("mutually_referential.Parent") 21 | -------------------------------------------------------------------------------- /tests/django20/timezones/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class Event(models.Model): 4 | dt = models.DateTimeField() 5 | 6 | class MaybeEvent(models.Model): 7 | dt = models.DateTimeField(blank=True, null=True) 8 | 9 | class Session(models.Model): 10 | name = models.CharField(max_length=20) 11 | 12 | class SessionEvent(models.Model): 13 | dt = models.DateTimeField() 14 | session = models.ForeignKey(Session, related_name='events') 15 | 16 | class Timestamp(models.Model): 17 | created = models.DateTimeField(auto_now_add=True) 18 | updated = models.DateTimeField(auto_now=True) 19 | 20 | class AllDayEvent(models.Model): 21 | day = models.DateField() 22 | -------------------------------------------------------------------------------- /tests/django20/bulk_create/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Country(models.Model): 5 | name = models.CharField(max_length=255) 6 | iso_two_letter = models.CharField(max_length=2) 7 | 8 | class Place(models.Model): 9 | name = models.CharField(max_length=100) 10 | 11 | class Meta: 12 | abstract = True 13 | 14 | class Restaurant(Place): 15 | pass 16 | 17 | class Pizzeria(Restaurant): 18 | pass 19 | 20 | class State(models.Model): 21 | two_letter_code = models.CharField(max_length=2, primary_key=True) 22 | 23 | class TwoFields(models.Model): 24 | f1 = models.IntegerField(unique=True) 25 | f2 = models.IntegerField(unique=True) 26 | -------------------------------------------------------------------------------- /tests/django20/indexes/models.py: -------------------------------------------------------------------------------- 1 | from django.db import connection 2 | from django.db import models 3 | 4 | 5 | class Article(models.Model): 6 | headline = models.CharField(max_length=100) 7 | pub_date = models.DateTimeField() 8 | 9 | class Meta: 10 | index_together = [ 11 | ["headline", "pub_date"], 12 | ] 13 | 14 | 15 | # Indexing a TextField on Oracle or MySQL results in index creation error. 16 | if connection.vendor == 'postgresql': 17 | class IndexedArticle(models.Model): 18 | headline = models.CharField(max_length=100, db_index=True) 19 | body = models.TextField(db_index=True) 20 | slug = models.CharField(max_length=40, unique=True) 21 | -------------------------------------------------------------------------------- /tests/django20/multiple_database/fixtures/multidb.other.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "multiple_database.person", 5 | "fields": { 6 | "name": "Mark Pilgrim" 7 | } 8 | }, 9 | { 10 | "pk": 2, 11 | "model": "multiple_database.person", 12 | "fields": { 13 | "name": "Chris Mills" 14 | } 15 | }, 16 | { 17 | "pk": 2, 18 | "model": "multiple_database.book", 19 | "fields": { 20 | "title": "Dive into Python", 21 | "published": "2009-5-4", 22 | "authors": [["Mark Pilgrim"]], 23 | "editor": ["Chris Mills"] 24 | } 25 | } 26 | ] -------------------------------------------------------------------------------- /tests/django20/multiple_database/fixtures/multidb.default.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "multiple_database.person", 5 | "fields": { 6 | "name": "Marty Alchin" 7 | } 8 | }, 9 | { 10 | "pk": 2, 11 | "model": "multiple_database.person", 12 | "fields": { 13 | "name": "George Vilches" 14 | } 15 | }, 16 | { 17 | "pk": 2, 18 | "model": "multiple_database.book", 19 | "fields": { 20 | "title": "Pro Django", 21 | "published": "2008-12-16", 22 | "authors": [["Marty Alchin"]], 23 | "editor": ["George Vilches"] 24 | } 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /tests/django20/known_related_objects/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Existing related object instance caching. 3 | 4 | Test that queries are not redone when going back through known relations. 5 | """ 6 | 7 | from django.db import models 8 | 9 | class Tournament(models.Model): 10 | name = models.CharField(max_length=30) 11 | 12 | class Organiser(models.Model): 13 | name = models.CharField(max_length=30) 14 | 15 | class Pool(models.Model): 16 | name = models.CharField(max_length=30) 17 | tournament = models.ForeignKey(Tournament) 18 | organiser = models.ForeignKey(Organiser) 19 | 20 | class PoolStyle(models.Model): 21 | name = models.CharField(max_length=30) 22 | pool = models.OneToOneField(Pool) 23 | 24 | -------------------------------------------------------------------------------- /tests/django20/mutually_referential/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import Parent 6 | 7 | 8 | class MutuallyReferentialTests(TestCase): 9 | 10 | def test_mutually_referential(self): 11 | # Create a Parent 12 | q = Parent(name='Elizabeth') 13 | q.save() 14 | 15 | # Create some children 16 | c = q.child_set.create(name='Charles') 17 | e = q.child_set.create(name='Edward') 18 | 19 | # Set the best child 20 | # No assertion require here; if basic assignment and 21 | # deletion works, the test passes. 22 | q.bestchild = c 23 | q.save() 24 | q.delete() 25 | -------------------------------------------------------------------------------- /tests/django20/nested_foreign_keys/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Person(models.Model): 5 | name = models.CharField(max_length=200) 6 | 7 | 8 | class Movie(models.Model): 9 | title = models.CharField(max_length=200) 10 | director = models.ForeignKey(Person) 11 | 12 | 13 | class Event(models.Model): 14 | pass 15 | 16 | 17 | class Screening(Event): 18 | movie = models.ForeignKey(Movie) 19 | 20 | class ScreeningNullFK(Event): 21 | movie = models.ForeignKey(Movie, null=True) 22 | 23 | 24 | class Package(models.Model): 25 | screening = models.ForeignKey(Screening, null=True) 26 | 27 | class PackageNullFK(models.Model): 28 | screening = models.ForeignKey(ScreeningNullFK, null=True) 29 | -------------------------------------------------------------------------------- /tests/django20/initial_sql_regress/sql/simple.sql: -------------------------------------------------------------------------------- 1 | -- a comment 2 | INSERT INTO initial_sql_regress_simple (name) VALUES ('John'); -- another comment 3 | INSERT INTO initial_sql_regress_simple (name) VALUES ('-- Comment Man'); 4 | INSERT INTO initial_sql_regress_simple (name) VALUES ('Paul'); 5 | INSERT INTO 6 | initial_sql_regress_simple (name) VALUES ('Ringo'); 7 | INSERT INTO initial_sql_regress_simple (name) VALUES ('George'); 8 | INSERT INTO initial_sql_regress_simple (name) VALUES ('Miles O''Brien'); 9 | INSERT INTO initial_sql_regress_simple (name) VALUES ('Semicolon;Man'); 10 | INSERT INTO initial_sql_regress_simple (name) VALUES ('"100%" of % are not placeholders'); 11 | INSERT INTO initial_sql_regress_simple (name) VALUES ('This line has a Windows line ending'); 12 | 13 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_same_model_name/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | XX. Model inheritance 3 | 4 | Model inheritance across apps can result in models with the same name resulting 5 | in the need for an %(app_label)s format string. This app specifically tests 6 | this feature by redefining the Copy model from model_inheritance/models.py 7 | """ 8 | 9 | from __future__ import absolute_import 10 | 11 | from django.db import models 12 | 13 | from model_inheritance.models import NamedURL 14 | from django.utils.encoding import python_2_unicode_compatible 15 | 16 | # 17 | # Abstract base classes with related models 18 | # 19 | @python_2_unicode_compatible 20 | class Copy(NamedURL): 21 | content = models.TextField() 22 | 23 | def __str__(self): 24 | return self.content 25 | -------------------------------------------------------------------------------- /tests/django20/or_lookups/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 19. OR lookups 3 | 4 | To perform an OR lookup, or a lookup that combines ANDs and ORs, combine 5 | ``QuerySet`` objects using ``&`` and ``|`` operators. 6 | 7 | Alternatively, use positional arguments, and pass one or more expressions of 8 | clauses using the variable ``django.db.models.Q`` (or any object with an 9 | ``add_to_query`` method). 10 | """ 11 | 12 | from django.db import models 13 | from django.utils.encoding import python_2_unicode_compatible 14 | 15 | 16 | @python_2_unicode_compatible 17 | class Article(models.Model): 18 | headline = models.CharField(max_length=50) 19 | pub_date = models.DateTimeField() 20 | 21 | class Meta: 22 | ordering = ('pub_date',) 23 | 24 | def __str__(self): 25 | return self.headline 26 | -------------------------------------------------------------------------------- /tests/django20/defer/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for defer() and only(). 3 | """ 4 | 5 | from django.db import models 6 | from django.utils.encoding import python_2_unicode_compatible 7 | 8 | 9 | class Secondary(models.Model): 10 | first = models.CharField(max_length=50) 11 | second = models.CharField(max_length=50) 12 | 13 | @python_2_unicode_compatible 14 | class Primary(models.Model): 15 | name = models.CharField(max_length=50) 16 | value = models.CharField(max_length=50) 17 | related = models.ForeignKey(Secondary) 18 | 19 | def __str__(self): 20 | return self.name 21 | 22 | class Child(Primary): 23 | pass 24 | 25 | class BigChild(Primary): 26 | other = models.CharField(max_length=50) 27 | 28 | class ChildProxy(Child): 29 | class Meta: 30 | proxy=True 31 | -------------------------------------------------------------------------------- /tests/django20/many_to_one_null/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 16. Many-to-one relationships that can be null 3 | 4 | To define a many-to-one relationship that can have a null foreign key, use 5 | ``ForeignKey()`` with ``null=True`` . 6 | """ 7 | 8 | from django.db import models 9 | from django.utils.encoding import python_2_unicode_compatible 10 | 11 | 12 | @python_2_unicode_compatible 13 | class Reporter(models.Model): 14 | name = models.CharField(max_length=30) 15 | 16 | def __str__(self): 17 | return self.name 18 | 19 | @python_2_unicode_compatible 20 | class Article(models.Model): 21 | headline = models.CharField(max_length=100) 22 | reporter = models.ForeignKey(Reporter, null=True) 23 | 24 | class Meta: 25 | ordering = ('headline',) 26 | 27 | def __str__(self): 28 | return self.headline 29 | -------------------------------------------------------------------------------- /tests/django20/transactions/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 15. Transactions 3 | 4 | Django handles transactions in three different ways. The default is to commit 5 | each transaction upon a write, but you can decorate a function to get 6 | commit-on-success behavior. Alternatively, you can manage the transaction 7 | manually. 8 | """ 9 | from __future__ import unicode_literals 10 | 11 | from django.db import models 12 | from django.utils.encoding import python_2_unicode_compatible 13 | 14 | 15 | @python_2_unicode_compatible 16 | class Reporter(models.Model): 17 | first_name = models.CharField(max_length=30) 18 | last_name = models.CharField(max_length=30) 19 | email = models.EmailField() 20 | 21 | class Meta: 22 | ordering = ('first_name', 'last_name') 23 | 24 | def __str__(self): 25 | return ("%s %s" % (self.first_name, self.last_name)).strip() 26 | -------------------------------------------------------------------------------- /tests/django20/m2m_through_regress/fixtures/m2m_through.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": "1", 4 | "model": "m2m_through_regress.person", 5 | "fields": { 6 | "name": "Guido" 7 | } 8 | }, 9 | { 10 | "pk": "1", 11 | "model": "auth.user", 12 | "fields": { 13 | "username": "Guido", 14 | "email": "bdfl@python.org", 15 | "password": "abcde" 16 | } 17 | }, 18 | { 19 | "pk": "1", 20 | "model": "m2m_through_regress.group", 21 | "fields": { 22 | "name": "Python Core Group" 23 | } 24 | }, 25 | { 26 | "pk": "1", 27 | "model": "m2m_through_regress.usermembership", 28 | "fields": { 29 | "user": "1", 30 | "group": "1", 31 | "price": "100" 32 | } 33 | } 34 | ] -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2015-2018 Lionheart Software LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | all: clean test publish 16 | 17 | clean: 18 | rm -rf dist/ 19 | 20 | test: 21 | python setup.py test 22 | 23 | publish: clean 24 | python3 setup.py bdist_wheel --universal 25 | gpg --detach-sign -a dist/*.whl 26 | twine upload dist/* 27 | -------------------------------------------------------------------------------- /tests/django20/expressions_regress/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | from django.utils.encoding import python_2_unicode_compatible 3 | """ 4 | Model for testing arithmetic expressions. 5 | """ 6 | from django.db import models 7 | 8 | 9 | @python_2_unicode_compatible 10 | class Number(models.Model): 11 | integer = models.IntegerField(db_column='the_integer') 12 | float = models.FloatField(null=True, db_column='the_float') 13 | 14 | def __str__(self): 15 | return '%i, %.3f' % (self.integer, self.float) 16 | 17 | class Experiment(models.Model): 18 | name = models.CharField(max_length=24) 19 | assigned = models.DateField() 20 | completed = models.DateField() 21 | start = models.DateTimeField() 22 | end = models.DateTimeField() 23 | 24 | class Meta: 25 | ordering = ('name',) 26 | 27 | def duration(self): 28 | return self.end - self.start 29 | 30 | -------------------------------------------------------------------------------- /tests/django20/dates/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Article(models.Model): 9 | title = models.CharField(max_length=100) 10 | pub_date = models.DateField() 11 | 12 | categories = models.ManyToManyField("Category", related_name="articles") 13 | 14 | def __str__(self): 15 | return self.title 16 | 17 | @python_2_unicode_compatible 18 | class Comment(models.Model): 19 | article = models.ForeignKey(Article, related_name="comments") 20 | text = models.TextField() 21 | pub_date = models.DateField() 22 | approval_date = models.DateField(null=True) 23 | 24 | def __str__(self): 25 | return 'Comment to %s (%s)' % (self.article.title, self.pub_date) 26 | 27 | class Category(models.Model): 28 | name = models.CharField(max_length=255) 29 | -------------------------------------------------------------------------------- /tests/django20/many_to_one/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 4. Many-to-one relationships 3 | 4 | To define a many-to-one relationship, use ``ForeignKey()``. 5 | """ 6 | from __future__ import unicode_literals 7 | 8 | from django.db import models 9 | from django.utils.encoding import python_2_unicode_compatible 10 | 11 | 12 | @python_2_unicode_compatible 13 | class Reporter(models.Model): 14 | first_name = models.CharField(max_length=30) 15 | last_name = models.CharField(max_length=30) 16 | email = models.EmailField() 17 | 18 | def __str__(self): 19 | return "%s %s" % (self.first_name, self.last_name) 20 | 21 | @python_2_unicode_compatible 22 | class Article(models.Model): 23 | headline = models.CharField(max_length=100) 24 | pub_date = models.DateField() 25 | reporter = models.ForeignKey(Reporter) 26 | 27 | def __str__(self): 28 | return self.headline 29 | 30 | class Meta: 31 | ordering = ('headline',) 32 | -------------------------------------------------------------------------------- /tests/django20/datetimes/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Article(models.Model): 9 | title = models.CharField(max_length=100) 10 | pub_date = models.DateTimeField() 11 | 12 | categories = models.ManyToManyField("Category", related_name="articles") 13 | 14 | def __str__(self): 15 | return self.title 16 | 17 | @python_2_unicode_compatible 18 | class Comment(models.Model): 19 | article = models.ForeignKey(Article, related_name="comments") 20 | text = models.TextField() 21 | pub_date = models.DateTimeField() 22 | approval_date = models.DateTimeField(null=True) 23 | 24 | def __str__(self): 25 | return 'Comment to %s (%s)' % (self.article.title, self.pub_date) 26 | 27 | class Category(models.Model): 28 | name = models.CharField(max_length=255) 29 | -------------------------------------------------------------------------------- /tests/django20/order_with_respect_to/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for the order_with_respect_to Meta attribute. 3 | """ 4 | 5 | from django.db import models 6 | from django.utils import six 7 | from django.utils.encoding import python_2_unicode_compatible 8 | 9 | 10 | class Question(models.Model): 11 | text = models.CharField(max_length=200) 12 | 13 | @python_2_unicode_compatible 14 | class Answer(models.Model): 15 | text = models.CharField(max_length=200) 16 | question = models.ForeignKey(Question) 17 | 18 | class Meta: 19 | order_with_respect_to = 'question' 20 | 21 | def __str__(self): 22 | return six.text_type(self.text) 23 | 24 | @python_2_unicode_compatible 25 | class Post(models.Model): 26 | title = models.CharField(max_length=200) 27 | parent = models.ForeignKey("self", related_name="children", null=True) 28 | 29 | class Meta: 30 | order_with_respect_to = "parent" 31 | 32 | def __str__(self): 33 | return self.title 34 | -------------------------------------------------------------------------------- /tests/django20/reverse_lookup/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 25. Reverse lookups 3 | 4 | This demonstrates the reverse lookup features of the database API. 5 | """ 6 | 7 | from django.db import models 8 | from django.utils.encoding import python_2_unicode_compatible 9 | 10 | 11 | @python_2_unicode_compatible 12 | class User(models.Model): 13 | name = models.CharField(max_length=200) 14 | 15 | def __str__(self): 16 | return self.name 17 | 18 | @python_2_unicode_compatible 19 | class Poll(models.Model): 20 | question = models.CharField(max_length=200) 21 | creator = models.ForeignKey(User) 22 | 23 | def __str__(self): 24 | return self.question 25 | 26 | @python_2_unicode_compatible 27 | class Choice(models.Model): 28 | name = models.CharField(max_length=100) 29 | poll = models.ForeignKey(Poll, related_name="poll_choice") 30 | related_poll = models.ForeignKey(Poll, related_name="related_choice") 31 | 32 | def __str__(self): 33 | return self.name 34 | -------------------------------------------------------------------------------- /tests/django20/basic/models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | 1. Bare-bones model 4 | 5 | This is a basic model with only two non-primary-key fields. 6 | """ 7 | from django.db import models 8 | from django.utils.encoding import python_2_unicode_compatible 9 | 10 | 11 | @python_2_unicode_compatible 12 | class Article(models.Model): 13 | headline = models.CharField(max_length=100, default='Default headline') 14 | pub_date = models.DateTimeField() 15 | 16 | class Meta: 17 | ordering = ('pub_date','headline') 18 | 19 | def __str__(self): 20 | return self.headline 21 | 22 | class ArticleSelectOnSave(Article): 23 | class Meta: 24 | proxy = True 25 | select_on_save = True 26 | 27 | @python_2_unicode_compatible 28 | class SelfRef(models.Model): 29 | selfref = models.ForeignKey('self', null=True, blank=True, 30 | related_name='+') 31 | 32 | def __str__(self): 33 | return SelfRef.objects.get(selfref=self).pk 34 | -------------------------------------------------------------------------------- /tests/django20/m2m_and_m2o/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 29. Many-to-many and many-to-one relationships to the same table 3 | 4 | Make sure to set ``related_name`` if you use relationships to the same table. 5 | """ 6 | from __future__ import unicode_literals 7 | 8 | from django.db import models 9 | from django.utils import six 10 | from django.utils.encoding import python_2_unicode_compatible 11 | 12 | 13 | class User(models.Model): 14 | username = models.CharField(max_length=20) 15 | 16 | @python_2_unicode_compatible 17 | class Issue(models.Model): 18 | num = models.IntegerField() 19 | cc = models.ManyToManyField(User, blank=True, related_name='test_issue_cc') 20 | client = models.ForeignKey(User, related_name='test_issue_client') 21 | 22 | def __str__(self): 23 | return six.text_type(self.num) 24 | 25 | class Meta: 26 | ordering = ('num',) 27 | 28 | class UnicodeReferenceModel(models.Model): 29 | others = models.ManyToManyField("UnicodeReferenceModel") 30 | 31 | -------------------------------------------------------------------------------- /tests/django20/datatypes/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a basic model to test saving and loading boolean and date-related 3 | types, which in the past were problematic for some database backends. 4 | """ 5 | 6 | from django.db import models 7 | from django.utils.encoding import python_2_unicode_compatible 8 | 9 | 10 | @python_2_unicode_compatible 11 | class Donut(models.Model): 12 | name = models.CharField(max_length=100) 13 | is_frosted = models.BooleanField(default=False) 14 | has_sprinkles = models.NullBooleanField() 15 | baked_date = models.DateField(null=True) 16 | baked_time = models.TimeField(null=True) 17 | consumed_at = models.DateTimeField(null=True) 18 | review = models.TextField() 19 | 20 | class Meta: 21 | ordering = ('consumed_at',) 22 | 23 | def __str__(self): 24 | return self.name 25 | 26 | class RumBaba(models.Model): 27 | baked_date = models.DateField(auto_now_add=True) 28 | baked_timestamp = models.DateTimeField(auto_now_add=True) 29 | -------------------------------------------------------------------------------- /tests/django20/null_queries/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Poll(models.Model): 9 | question = models.CharField(max_length=200) 10 | 11 | def __str__(self): 12 | return "Q: %s " % self.question 13 | 14 | @python_2_unicode_compatible 15 | class Choice(models.Model): 16 | poll = models.ForeignKey(Poll) 17 | choice = models.CharField(max_length=200) 18 | 19 | def __str__(self): 20 | return "Choice: %s in poll %s" % (self.choice, self.poll) 21 | 22 | # A set of models with an inner one pointing to two outer ones. 23 | class OuterA(models.Model): 24 | pass 25 | 26 | class OuterB(models.Model): 27 | data = models.CharField(max_length=10) 28 | 29 | class Inner(models.Model): 30 | first = models.ForeignKey(OuterA) 31 | # second would clash with the __second lookup. 32 | third = models.ForeignKey(OuterB, null=True) 33 | -------------------------------------------------------------------------------- /tests/django20/expressions/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for F() query expression syntax. 3 | """ 4 | from __future__ import unicode_literals 5 | 6 | from django.db import models 7 | from django.utils.encoding import python_2_unicode_compatible 8 | 9 | 10 | @python_2_unicode_compatible 11 | class Employee(models.Model): 12 | firstname = models.CharField(max_length=50) 13 | lastname = models.CharField(max_length=50) 14 | 15 | def __str__(self): 16 | return '%s %s' % (self.firstname, self.lastname) 17 | 18 | @python_2_unicode_compatible 19 | class Company(models.Model): 20 | name = models.CharField(max_length=100) 21 | num_employees = models.PositiveIntegerField() 22 | num_chairs = models.PositiveIntegerField() 23 | ceo = models.ForeignKey( 24 | Employee, 25 | related_name='company_ceo_set') 26 | point_of_contact = models.ForeignKey( 27 | Employee, 28 | related_name='company_point_of_contact_set', 29 | null=True) 30 | 31 | def __str__(self): 32 | return self.name 33 | -------------------------------------------------------------------------------- /tests/django20/reserved_names/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 18. Using SQL reserved names 3 | 4 | Need to use a reserved SQL name as a column name or table name? Need to include 5 | a hyphen in a column or table name? No problem. Django quotes names 6 | appropriately behind the scenes, so your database won't complain about 7 | reserved-name usage. 8 | """ 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | @python_2_unicode_compatible 15 | class Thing(models.Model): 16 | when = models.CharField(max_length=1, primary_key=True) 17 | join = models.CharField(max_length=1) 18 | like = models.CharField(max_length=1) 19 | drop = models.CharField(max_length=1) 20 | alter = models.CharField(max_length=1) 21 | having = models.CharField(max_length=1) 22 | where = models.DateField(max_length=1) 23 | has_hyphen = models.CharField(max_length=1, db_column='has-hyphen') 24 | class Meta: 25 | db_table = 'select' 26 | 27 | def __str__(self): 28 | return self.when 29 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_select_related/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for the interaction between model inheritance and 3 | select_related(). 4 | """ 5 | from __future__ import unicode_literals 6 | 7 | from django.db import models 8 | from django.utils.encoding import python_2_unicode_compatible 9 | 10 | 11 | @python_2_unicode_compatible 12 | class Place(models.Model): 13 | name = models.CharField(max_length=50) 14 | 15 | class Meta: 16 | ordering = ('name',) 17 | 18 | def __str__(self): 19 | return "%s the place" % self.name 20 | 21 | @python_2_unicode_compatible 22 | class Restaurant(Place): 23 | serves_sushi = models.BooleanField(default=False) 24 | serves_steak = models.BooleanField(default=False) 25 | 26 | def __str__(self): 27 | return "%s the restaurant" % self.name 28 | 29 | @python_2_unicode_compatible 30 | class Person(models.Model): 31 | name = models.CharField(max_length=50) 32 | favorite_restaurant = models.ForeignKey(Restaurant) 33 | 34 | def __str__(self): 35 | return self.name 36 | -------------------------------------------------------------------------------- /tests/django20/timezones/fixtures/tz_users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | super 5 | Super 6 | User 7 | super@example.com 8 | sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158 9 | True 10 | True 11 | True 12 | 2001-01-01 00:00:00+00:00 13 | 2001-01-01 00:00:00+00:00 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/django20/m2o_recursive/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 11. Relating an object to itself, many-to-one 3 | 4 | To define a many-to-one relationship between a model and itself, use 5 | ``ForeignKey('self')``. 6 | 7 | In this example, a ``Category`` is related to itself. That is, each 8 | ``Category`` has a parent ``Category``. 9 | 10 | Set ``related_name`` to designate what the reverse relationship is called. 11 | """ 12 | 13 | from django.db import models 14 | from django.utils.encoding import python_2_unicode_compatible 15 | 16 | 17 | @python_2_unicode_compatible 18 | class Category(models.Model): 19 | name = models.CharField(max_length=20) 20 | parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set') 21 | 22 | def __str__(self): 23 | return self.name 24 | 25 | @python_2_unicode_compatible 26 | class Person(models.Model): 27 | full_name = models.CharField(max_length=20) 28 | mother = models.ForeignKey('self', null=True, related_name='mothers_child_set') 29 | father = models.ForeignKey('self', null=True, related_name='fathers_child_set') 30 | 31 | def __str__(self): 32 | return self.full_name 33 | -------------------------------------------------------------------------------- /tests/django20/update/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for the update() queryset method that allows in-place, multi-object 3 | updates. 4 | """ 5 | 6 | from django.db import models 7 | from django.utils import six 8 | from django.utils.encoding import python_2_unicode_compatible 9 | 10 | 11 | @python_2_unicode_compatible 12 | class DataPoint(models.Model): 13 | name = models.CharField(max_length=20) 14 | value = models.CharField(max_length=20) 15 | another_value = models.CharField(max_length=20, blank=True) 16 | 17 | def __str__(self): 18 | return six.text_type(self.name) 19 | 20 | @python_2_unicode_compatible 21 | class RelatedPoint(models.Model): 22 | name = models.CharField(max_length=20) 23 | data = models.ForeignKey(DataPoint) 24 | 25 | def __str__(self): 26 | return six.text_type(self.name) 27 | 28 | 29 | class A(models.Model): 30 | x = models.IntegerField(default=10) 31 | 32 | class B(models.Model): 33 | a = models.ForeignKey(A) 34 | y = models.IntegerField(default=10) 35 | 36 | class C(models.Model): 37 | y = models.IntegerField(default=10) 38 | 39 | class D(C): 40 | a = models.ForeignKey(A) 41 | -------------------------------------------------------------------------------- /tests/django20/many_to_many/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 5. Many-to-many relationships 3 | 4 | To define a many-to-many relationship, use ``ManyToManyField()``. 5 | 6 | In this example, an ``Article`` can be published in multiple ``Publication`` 7 | objects, and a ``Publication`` has multiple ``Article`` objects. 8 | """ 9 | from __future__ import unicode_literals 10 | 11 | from django.db import models 12 | from django.utils.encoding import python_2_unicode_compatible 13 | 14 | 15 | @python_2_unicode_compatible 16 | class Publication(models.Model): 17 | title = models.CharField(max_length=30) 18 | 19 | def __str__(self): 20 | return self.title 21 | 22 | class Meta: 23 | ordering = ('title',) 24 | 25 | @python_2_unicode_compatible 26 | class Article(models.Model): 27 | headline = models.CharField(max_length=100) 28 | # Assign a unicode string as name to make sure the intermediary model is 29 | # correctly created. Refs #20207 30 | publications = models.ManyToManyField(Publication, name='publications') 31 | 32 | def __str__(self): 33 | return self.headline 34 | 35 | class Meta: 36 | ordering = ('headline',) 37 | -------------------------------------------------------------------------------- /tests/django20/m2m_multiple/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 20. Multiple many-to-many relationships between the same two tables 3 | 4 | In this example, an ``Article`` can have many "primary" ``Category`` objects 5 | and many "secondary" ``Category`` objects. 6 | 7 | Set ``related_name`` to designate what the reverse relationship is called. 8 | """ 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | @python_2_unicode_compatible 15 | class Category(models.Model): 16 | name = models.CharField(max_length=20) 17 | class Meta: 18 | ordering = ('name',) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | @python_2_unicode_compatible 24 | class Article(models.Model): 25 | headline = models.CharField(max_length=50) 26 | pub_date = models.DateTimeField() 27 | primary_categories = models.ManyToManyField(Category, related_name='primary_article_set') 28 | secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set') 29 | class Meta: 30 | ordering = ('pub_date',) 31 | 32 | def __str__(self): 33 | return self.headline 34 | 35 | -------------------------------------------------------------------------------- /tests/django20/introspection/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Reporter(models.Model): 9 | first_name = models.CharField(max_length=30) 10 | last_name = models.CharField(max_length=30) 11 | email = models.EmailField() 12 | facebook_user_id = models.BigIntegerField(null=True) 13 | raw_data = models.BinaryField(null=True) 14 | 15 | class Meta: 16 | unique_together = ('first_name', 'last_name') 17 | 18 | def __str__(self): 19 | return "%s %s" % (self.first_name, self.last_name) 20 | 21 | 22 | @python_2_unicode_compatible 23 | class Article(models.Model): 24 | headline = models.CharField(max_length=100) 25 | pub_date = models.DateField() 26 | reporter = models.ForeignKey(Reporter) 27 | response_to = models.ForeignKey('self', null=True) 28 | 29 | def __str__(self): 30 | return self.headline 31 | 32 | class Meta: 33 | ordering = ('headline',) 34 | index_together = [ 35 | ["headline", "pub_date"], 36 | ] 37 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_select_related/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from operator import attrgetter 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Restaurant, Person 8 | 9 | 10 | class ModelInheritanceSelectRelatedTests(TestCase): 11 | def test_inherited_select_related(self): 12 | # Regression test for #7246 13 | r1 = Restaurant.objects.create( 14 | name="Nobu", serves_sushi=True, serves_steak=False 15 | ) 16 | r2 = Restaurant.objects.create( 17 | name="Craft", serves_sushi=False, serves_steak=True 18 | ) 19 | p1 = Person.objects.create(name="John", favorite_restaurant=r1) 20 | p2 = Person.objects.create(name="Jane", favorite_restaurant=r2) 21 | 22 | self.assertQuerysetEqual( 23 | Person.objects.order_by("name").select_related(), [ 24 | "Jane", 25 | "John", 26 | ], 27 | attrgetter("name") 28 | ) 29 | 30 | jane = Person.objects.order_by("name").select_related("favorite_restaurant")[0] 31 | self.assertEqual(jane.favorite_restaurant.name, "Craft") 32 | -------------------------------------------------------------------------------- /tests/django20/raw_query/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Author(models.Model): 5 | first_name = models.CharField(max_length=255) 6 | last_name = models.CharField(max_length=255) 7 | dob = models.DateField() 8 | 9 | def __init__(self, *args, **kwargs): 10 | super(Author, self).__init__(*args, **kwargs) 11 | # Protect against annotations being passed to __init__ -- 12 | # this'll make the test suite get angry if annotations aren't 13 | # treated differently than fields. 14 | for k in kwargs: 15 | assert k in [f.attname for f in self._meta.fields], \ 16 | "Author.__init__ got an unexpected parameter: %s" % k 17 | 18 | class Book(models.Model): 19 | title = models.CharField(max_length=255) 20 | author = models.ForeignKey(Author) 21 | paperback = models.BooleanField(default=False) 22 | opening_line = models.TextField() 23 | 24 | class Coffee(models.Model): 25 | brand = models.CharField(max_length=255, db_column="name") 26 | 27 | class Reviewer(models.Model): 28 | reviewed = models.ManyToManyField(Book) 29 | 30 | class FriendlyAuthor(Author): 31 | pass 32 | -------------------------------------------------------------------------------- /tests/django20/m2m_signals/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils.encoding import python_2_unicode_compatible 3 | 4 | 5 | @python_2_unicode_compatible 6 | class Part(models.Model): 7 | name = models.CharField(max_length=20) 8 | 9 | class Meta: 10 | ordering = ('name',) 11 | 12 | def __str__(self): 13 | return self.name 14 | 15 | @python_2_unicode_compatible 16 | class Car(models.Model): 17 | name = models.CharField(max_length=20) 18 | default_parts = models.ManyToManyField(Part) 19 | optional_parts = models.ManyToManyField(Part, related_name='cars_optional') 20 | 21 | class Meta: 22 | ordering = ('name',) 23 | 24 | def __str__(self): 25 | return self.name 26 | 27 | class SportsCar(Car): 28 | price = models.IntegerField() 29 | 30 | @python_2_unicode_compatible 31 | class Person(models.Model): 32 | name = models.CharField(max_length=20) 33 | fans = models.ManyToManyField('self', related_name='idols', symmetrical=False) 34 | friends = models.ManyToManyField('self') 35 | 36 | class Meta: 37 | ordering = ('name',) 38 | 39 | def __str__(self): 40 | return self.name 41 | -------------------------------------------------------------------------------- /tests/django20/update_only_fields/models.py: -------------------------------------------------------------------------------- 1 | 2 | from django.db import models 3 | from django.utils.encoding import python_2_unicode_compatible 4 | 5 | GENDER_CHOICES = ( 6 | ('M', 'Male'), 7 | ('F', 'Female'), 8 | ) 9 | 10 | class Account(models.Model): 11 | num = models.IntegerField() 12 | 13 | 14 | @python_2_unicode_compatible 15 | class Person(models.Model): 16 | name = models.CharField(max_length=20) 17 | gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 18 | pid = models.IntegerField(null=True, default=None) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | 24 | class Employee(Person): 25 | employee_num = models.IntegerField(default=0) 26 | profile = models.ForeignKey('Profile', related_name='profiles', null=True) 27 | accounts = models.ManyToManyField('Account', related_name='employees', blank=True, null=True) 28 | 29 | 30 | @python_2_unicode_compatible 31 | class Profile(models.Model): 32 | name = models.CharField(max_length=200) 33 | salary = models.FloatField(default=1000.0) 34 | 35 | def __str__(self): 36 | return self.name 37 | 38 | 39 | class ProxyEmployee(Employee): 40 | class Meta: 41 | proxy = True 42 | -------------------------------------------------------------------------------- /tests/django20/m2m_recursive/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 28. Many-to-many relationships between the same two tables 3 | 4 | In this example, a ``Person`` can have many friends, who are also ``Person`` 5 | objects. Friendship is a symmetrical relationship - if I am your friend, you 6 | are my friend. Here, ``friends`` is an example of a symmetrical 7 | ``ManyToManyField``. 8 | 9 | A ``Person`` can also have many idols - but while I may idolize you, you may 10 | not think the same of me. Here, ``idols`` is an example of a non-symmetrical 11 | ``ManyToManyField``. Only recursive ``ManyToManyField`` fields may be 12 | non-symmetrical, and they are symmetrical by default. 13 | 14 | This test validates that the many-to-many table is created using a mangled name 15 | if there is a name clash, and tests that symmetry is preserved where 16 | appropriate. 17 | """ 18 | 19 | from django.db import models 20 | from django.utils.encoding import python_2_unicode_compatible 21 | 22 | 23 | @python_2_unicode_compatible 24 | class Person(models.Model): 25 | name = models.CharField(max_length=20) 26 | friends = models.ManyToManyField('self') 27 | idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers') 28 | 29 | def __str__(self): 30 | return self.name 31 | -------------------------------------------------------------------------------- /tests/django20/get_object_or_404/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 35. DB-API Shortcuts 3 | 4 | ``get_object_or_404()`` is a shortcut function to be used in view functions for 5 | performing a ``get()`` lookup and raising a ``Http404`` exception if a 6 | ``DoesNotExist`` exception was raised during the ``get()`` call. 7 | 8 | ``get_list_or_404()`` is a shortcut function to be used in view functions for 9 | performing a ``filter()`` lookup and raising a ``Http404`` exception if a 10 | ``DoesNotExist`` exception was raised during the ``filter()`` call. 11 | """ 12 | 13 | from django.db import models 14 | from django.utils.encoding import python_2_unicode_compatible 15 | 16 | 17 | @python_2_unicode_compatible 18 | class Author(models.Model): 19 | name = models.CharField(max_length=50) 20 | 21 | def __str__(self): 22 | return self.name 23 | 24 | class ArticleManager(models.Manager): 25 | def get_queryset(self): 26 | return super(ArticleManager, self).get_queryset().filter(authors__name__icontains='sir') 27 | 28 | @python_2_unicode_compatible 29 | class Article(models.Model): 30 | authors = models.ManyToManyField(Author) 31 | title = models.CharField(max_length=50) 32 | objects = models.Manager() 33 | by_a_sir = ArticleManager() 34 | 35 | def __str__(self): 36 | return self.title 37 | -------------------------------------------------------------------------------- /tests/django20/ordering/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 6. Specifying ordering 3 | 4 | Specify default ordering for a model using the ``ordering`` attribute, which 5 | should be a list or tuple of field names. This tells Django how to order 6 | ``QuerySet`` results. 7 | 8 | If a field name in ``ordering`` starts with a hyphen, that field will be 9 | ordered in descending order. Otherwise, it'll be ordered in ascending order. 10 | The special-case field name ``"?"`` specifies random order. 11 | 12 | The ordering attribute is not required. If you leave it off, ordering will be 13 | undefined -- not random, just undefined. 14 | """ 15 | 16 | from django.db import models 17 | from django.utils.encoding import python_2_unicode_compatible 18 | 19 | 20 | @python_2_unicode_compatible 21 | class Article(models.Model): 22 | headline = models.CharField(max_length=100) 23 | pub_date = models.DateTimeField() 24 | class Meta: 25 | ordering = ('-pub_date', 'headline') 26 | 27 | def __str__(self): 28 | return self.headline 29 | 30 | @python_2_unicode_compatible 31 | class ArticlePKOrdering(models.Model): 32 | headline = models.CharField(max_length=100) 33 | pub_date = models.DateTimeField() 34 | class Meta: 35 | ordering = ('-pk',) 36 | 37 | def __str__(self): 38 | return self.headline 39 | -------------------------------------------------------------------------------- /tests/django20/get_or_create/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 33. get_or_create() 3 | 4 | ``get_or_create()`` does what it says: it tries to look up an object with the 5 | given parameters. If an object isn't found, it creates one with the given 6 | parameters. 7 | """ 8 | 9 | from __future__ import unicode_literals 10 | 11 | from django.db import models 12 | from django.utils.encoding import python_2_unicode_compatible 13 | 14 | 15 | @python_2_unicode_compatible 16 | class Person(models.Model): 17 | first_name = models.CharField(max_length=100) 18 | last_name = models.CharField(max_length=100) 19 | birthday = models.DateField() 20 | 21 | def __str__(self): 22 | return '%s %s' % (self.first_name, self.last_name) 23 | 24 | 25 | class DefaultPerson(models.Model): 26 | first_name = models.CharField(max_length=100, default="Anonymous") 27 | 28 | 29 | class ManualPrimaryKeyTest(models.Model): 30 | id = models.IntegerField(primary_key=True) 31 | data = models.CharField(max_length=100) 32 | 33 | 34 | class Profile(models.Model): 35 | person = models.ForeignKey(Person, primary_key=True) 36 | 37 | 38 | class Tag(models.Model): 39 | text = models.CharField(max_length=255, unique=True) 40 | 41 | 42 | class Thing(models.Model): 43 | name = models.CharField(max_length=256) 44 | tags = models.ManyToManyField(Tag) 45 | -------------------------------------------------------------------------------- /tests/django20/indexes/tests.py: -------------------------------------------------------------------------------- 1 | from django.core.management.color import no_style 2 | from django.db import connections, DEFAULT_DB_ALIAS 3 | from django.test import TestCase 4 | from django.utils.unittest import skipUnless 5 | 6 | from .models import Article 7 | 8 | 9 | class IndexesTests(TestCase): 10 | def test_index_together(self): 11 | connection = connections[DEFAULT_DB_ALIAS] 12 | index_sql = connection.creation.sql_indexes_for_model(Article, no_style()) 13 | self.assertEqual(len(index_sql), 1) 14 | 15 | @skipUnless(connections[DEFAULT_DB_ALIAS].vendor == 'postgresql', 16 | "This is a postgresql-specific issue") 17 | def test_postgresql_text_indexes(self): 18 | """Test creation of PostgreSQL-specific text indexes (#12234)""" 19 | from .models import IndexedArticle 20 | connection = connections[DEFAULT_DB_ALIAS] 21 | index_sql = connection.creation.sql_indexes_for_model(IndexedArticle, no_style()) 22 | self.assertEqual(len(index_sql), 5) 23 | self.assertIn('("headline" varchar_pattern_ops)', index_sql[1]) 24 | self.assertIn('("body" text_pattern_ops)', index_sql[3]) 25 | # unique=True and db_index=True should only create the varchar-specific 26 | # index (#19441). 27 | self.assertIn('("slug" varchar_pattern_ops)', index_sql[4]) 28 | -------------------------------------------------------------------------------- /tests/django20/custom_columns_regress/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression for #9736. 3 | 4 | Checks some pathological column naming to make sure it doesn't break 5 | table creation or queries. 6 | 7 | """ 8 | from __future__ import unicode_literals 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | @python_2_unicode_compatible 15 | class Article(models.Model): 16 | Article_ID = models.AutoField(primary_key=True, db_column='Article ID') 17 | headline = models.CharField(max_length=100) 18 | authors = models.ManyToManyField('Author', db_table='my m2m table') 19 | primary_author = models.ForeignKey('Author', db_column='Author ID', related_name='primary_set') 20 | 21 | def __str__(self): 22 | return self.headline 23 | 24 | class Meta: 25 | ordering = ('headline',) 26 | 27 | @python_2_unicode_compatible 28 | class Author(models.Model): 29 | Author_ID = models.AutoField(primary_key=True, db_column='Author ID') 30 | first_name = models.CharField(max_length=30, db_column='first name') 31 | last_name = models.CharField(max_length=30, db_column='last name') 32 | 33 | def __str__(self): 34 | return '%s %s' % (self.first_name, self.last_name) 35 | 36 | class Meta: 37 | db_table = 'my author table' 38 | ordering = ('last_name','first_name') 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/django20/custom_methods/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from datetime import date 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Article 8 | 9 | 10 | class MethodsTests(TestCase): 11 | def test_custom_methods(self): 12 | a = Article.objects.create( 13 | headline="Area man programs in Python", pub_date=date(2005, 7, 27) 14 | ) 15 | b = Article.objects.create( 16 | headline="Beatles reunite", pub_date=date(2005, 7, 27) 17 | ) 18 | 19 | self.assertFalse(a.was_published_today()) 20 | self.assertQuerysetEqual( 21 | a.articles_from_same_day_1(), [ 22 | "Beatles reunite", 23 | ], 24 | lambda a: a.headline, 25 | ) 26 | self.assertQuerysetEqual( 27 | a.articles_from_same_day_2(), [ 28 | "Beatles reunite", 29 | ], 30 | lambda a: a.headline 31 | ) 32 | 33 | self.assertQuerysetEqual( 34 | b.articles_from_same_day_1(), [ 35 | "Area man programs in Python", 36 | ], 37 | lambda a: a.headline, 38 | ) 39 | self.assertQuerysetEqual( 40 | b.articles_from_same_day_2(), [ 41 | "Area man programs in Python", 42 | ], 43 | lambda a: a.headline 44 | ) 45 | -------------------------------------------------------------------------------- /tests/django20/custom_managers_regress/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for custom manager classes. 3 | """ 4 | 5 | from django.db import models 6 | from django.utils.encoding import python_2_unicode_compatible 7 | 8 | 9 | class RestrictedManager(models.Manager): 10 | """ 11 | A manager that filters out non-public instances. 12 | """ 13 | def get_queryset(self): 14 | return super(RestrictedManager, self).get_queryset().filter(is_public=True) 15 | 16 | @python_2_unicode_compatible 17 | class RelatedModel(models.Model): 18 | name = models.CharField(max_length=50) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | @python_2_unicode_compatible 24 | class RestrictedModel(models.Model): 25 | name = models.CharField(max_length=50) 26 | is_public = models.BooleanField(default=False) 27 | related = models.ForeignKey(RelatedModel) 28 | 29 | objects = RestrictedManager() 30 | plain_manager = models.Manager() 31 | 32 | def __str__(self): 33 | return self.name 34 | 35 | @python_2_unicode_compatible 36 | class OneToOneRestrictedModel(models.Model): 37 | name = models.CharField(max_length=50) 38 | is_public = models.BooleanField(default=False) 39 | related = models.OneToOneField(RelatedModel) 40 | 41 | objects = RestrictedManager() 42 | plain_manager = models.Manager() 43 | 44 | def __str__(self): 45 | return self.name 46 | -------------------------------------------------------------------------------- /tests/django20/custom_methods/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3. Giving models custom methods 3 | 4 | Any method you add to a model will be available to instances. 5 | """ 6 | 7 | import datetime 8 | 9 | from django.db import models 10 | from django.utils.encoding import python_2_unicode_compatible 11 | 12 | 13 | @python_2_unicode_compatible 14 | class Article(models.Model): 15 | headline = models.CharField(max_length=100) 16 | pub_date = models.DateField() 17 | 18 | def __str__(self): 19 | return self.headline 20 | 21 | def was_published_today(self): 22 | return self.pub_date == datetime.date.today() 23 | 24 | def articles_from_same_day_1(self): 25 | return Article.objects.filter(pub_date=self.pub_date).exclude(id=self.id) 26 | 27 | def articles_from_same_day_2(self): 28 | """ 29 | Verbose version of get_articles_from_same_day_1, which does a custom 30 | database query for the sake of demonstration. 31 | """ 32 | from django.db import connection 33 | cursor = connection.cursor() 34 | cursor.execute(""" 35 | SELECT id, headline, pub_date 36 | FROM custom_methods_article 37 | WHERE pub_date = %s 38 | AND id != %s""", [connection.ops.value_to_db_date(self.pub_date), 39 | self.id]) 40 | return [self.__class__(*row) for row in cursor.fetchall()] 41 | -------------------------------------------------------------------------------- /tests/django20/m2m_intermediary/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 9. Many-to-many relationships via an intermediary table 3 | 4 | For many-to-many relationships that need extra fields on the intermediary 5 | table, use an intermediary model. 6 | 7 | In this example, an ``Article`` can have multiple ``Reporter`` objects, and 8 | each ``Article``-``Reporter`` combination (a ``Writer``) has a ``position`` 9 | field, which specifies the ``Reporter``'s position for the given article 10 | (e.g. "Staff writer"). 11 | """ 12 | from __future__ import unicode_literals 13 | 14 | from django.db import models 15 | from django.utils.encoding import python_2_unicode_compatible 16 | 17 | 18 | @python_2_unicode_compatible 19 | class Reporter(models.Model): 20 | first_name = models.CharField(max_length=30) 21 | last_name = models.CharField(max_length=30) 22 | 23 | def __str__(self): 24 | return "%s %s" % (self.first_name, self.last_name) 25 | 26 | @python_2_unicode_compatible 27 | class Article(models.Model): 28 | headline = models.CharField(max_length=100) 29 | pub_date = models.DateField() 30 | 31 | def __str__(self): 32 | return self.headline 33 | 34 | @python_2_unicode_compatible 35 | class Writer(models.Model): 36 | reporter = models.ForeignKey(Reporter) 37 | article = models.ForeignKey(Article) 38 | position = models.CharField(max_length=100) 39 | 40 | def __str__(self): 41 | return '%s (%s)' % (self.reporter, self.position) 42 | 43 | -------------------------------------------------------------------------------- /tests/django20/custom_pk/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 14. Using a custom primary key 4 | 5 | By default, Django adds an ``"id"`` field to each model. But you can override 6 | this behavior by explicitly adding ``primary_key=True`` to a field. 7 | """ 8 | 9 | from __future__ import absolute_import, unicode_literals 10 | 11 | from django.db import models 12 | 13 | from .fields import MyAutoField 14 | from django.utils.encoding import python_2_unicode_compatible 15 | 16 | 17 | @python_2_unicode_compatible 18 | class Employee(models.Model): 19 | employee_code = models.IntegerField(primary_key=True, db_column = 'code') 20 | first_name = models.CharField(max_length=20) 21 | last_name = models.CharField(max_length=20) 22 | class Meta: 23 | ordering = ('last_name', 'first_name') 24 | 25 | def __str__(self): 26 | return "%s %s" % (self.first_name, self.last_name) 27 | 28 | @python_2_unicode_compatible 29 | class Business(models.Model): 30 | name = models.CharField(max_length=20, primary_key=True) 31 | employees = models.ManyToManyField(Employee) 32 | class Meta: 33 | verbose_name_plural = 'businesses' 34 | 35 | def __str__(self): 36 | return self.name 37 | 38 | @python_2_unicode_compatible 39 | class Bar(models.Model): 40 | id = MyAutoField(primary_key=True, db_index=True) 41 | 42 | def __str__(self): 43 | return repr(self.pk) 44 | 45 | 46 | class Foo(models.Model): 47 | bar = models.ForeignKey(Bar) 48 | 49 | -------------------------------------------------------------------------------- /tests/django20/distinct_on_fields/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | @python_2_unicode_compatible 7 | class Tag(models.Model): 8 | name = models.CharField(max_length=10) 9 | parent = models.ForeignKey('self', blank=True, null=True, 10 | related_name='children') 11 | 12 | class Meta: 13 | ordering = ['name'] 14 | 15 | def __str__(self): 16 | return self.name 17 | 18 | @python_2_unicode_compatible 19 | class Celebrity(models.Model): 20 | name = models.CharField("Name", max_length=20) 21 | greatest_fan = models.ForeignKey("Fan", null=True, unique=True) 22 | 23 | def __str__(self): 24 | return self.name 25 | 26 | class Fan(models.Model): 27 | fan_of = models.ForeignKey(Celebrity) 28 | 29 | @python_2_unicode_compatible 30 | class Staff(models.Model): 31 | id = models.IntegerField(primary_key=True) 32 | name = models.CharField(max_length=50) 33 | organisation = models.CharField(max_length=100) 34 | tags = models.ManyToManyField(Tag, through='StaffTag') 35 | coworkers = models.ManyToManyField('self') 36 | 37 | def __str__(self): 38 | return self.name 39 | 40 | @python_2_unicode_compatible 41 | class StaffTag(models.Model): 42 | staff = models.ForeignKey(Staff) 43 | tag = models.ForeignKey(Tag) 44 | 45 | def __str__(self): 46 | return "%s -> %s" % (self.tag, self.staff) 47 | -------------------------------------------------------------------------------- /tests/django20/m2m_intermediary/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from datetime import datetime 4 | 5 | from django.test import TestCase 6 | from django.utils import six 7 | 8 | from .models import Reporter, Article, Writer 9 | 10 | 11 | class M2MIntermediaryTests(TestCase): 12 | def test_intermeiary(self): 13 | r1 = Reporter.objects.create(first_name="John", last_name="Smith") 14 | r2 = Reporter.objects.create(first_name="Jane", last_name="Doe") 15 | 16 | a = Article.objects.create( 17 | headline="This is a test", pub_date=datetime(2005, 7, 27) 18 | ) 19 | 20 | w1 = Writer.objects.create(reporter=r1, article=a, position="Main writer") 21 | w2 = Writer.objects.create(reporter=r2, article=a, position="Contributor") 22 | 23 | self.assertQuerysetEqual( 24 | a.writer_set.select_related().order_by("-position"), [ 25 | ("John Smith", "Main writer"), 26 | ("Jane Doe", "Contributor"), 27 | ], 28 | lambda w: (six.text_type(w.reporter), w.position) 29 | ) 30 | self.assertEqual(w1.reporter, r1) 31 | self.assertEqual(w2.reporter, r2) 32 | 33 | self.assertEqual(w1.article, a) 34 | self.assertEqual(w2.article, a) 35 | 36 | self.assertQuerysetEqual( 37 | r1.writer_set.all(), [ 38 | ("John Smith", "Main writer") 39 | ], 40 | lambda w: (six.text_type(w.reporter), w.position) 41 | ) 42 | -------------------------------------------------------------------------------- /tests/django20/null_fk/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for proper working of ForeignKey(null=True). 3 | """ 4 | 5 | from django.db import models 6 | from django.utils.encoding import python_2_unicode_compatible 7 | 8 | 9 | class SystemDetails(models.Model): 10 | details = models.TextField() 11 | 12 | class SystemInfo(models.Model): 13 | system_details = models.ForeignKey(SystemDetails) 14 | system_name = models.CharField(max_length=32) 15 | 16 | class Forum(models.Model): 17 | system_info = models.ForeignKey(SystemInfo) 18 | forum_name = models.CharField(max_length=32) 19 | 20 | @python_2_unicode_compatible 21 | class Post(models.Model): 22 | forum = models.ForeignKey(Forum, null=True) 23 | title = models.CharField(max_length=32) 24 | 25 | def __str__(self): 26 | return self.title 27 | 28 | @python_2_unicode_compatible 29 | class Comment(models.Model): 30 | post = models.ForeignKey(Post, null=True) 31 | comment_text = models.CharField(max_length=250) 32 | 33 | class Meta: 34 | ordering = ('comment_text',) 35 | 36 | def __str__(self): 37 | return self.comment_text 38 | 39 | # Ticket 15823 40 | 41 | class Item(models.Model): 42 | title = models.CharField(max_length=100) 43 | 44 | class PropertyValue(models.Model): 45 | label = models.CharField(max_length=100) 46 | 47 | class Property(models.Model): 48 | item = models.ForeignKey(Item, related_name='props') 49 | key = models.CharField(max_length=100) 50 | value = models.ForeignKey(PropertyValue, null=True) 51 | -------------------------------------------------------------------------------- /tests/django20/aggregation/models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from django.db import models 3 | from django.utils.encoding import python_2_unicode_compatible 4 | 5 | 6 | @python_2_unicode_compatible 7 | class Author(models.Model): 8 | name = models.CharField(max_length=100) 9 | age = models.IntegerField() 10 | friends = models.ManyToManyField('self', blank=True) 11 | 12 | def __str__(self): 13 | return self.name 14 | 15 | @python_2_unicode_compatible 16 | class Publisher(models.Model): 17 | name = models.CharField(max_length=255) 18 | num_awards = models.IntegerField() 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | @python_2_unicode_compatible 24 | class Book(models.Model): 25 | isbn = models.CharField(max_length=9) 26 | name = models.CharField(max_length=255) 27 | pages = models.IntegerField() 28 | rating = models.FloatField() 29 | price = models.DecimalField(decimal_places=2, max_digits=6) 30 | authors = models.ManyToManyField(Author) 31 | contact = models.ForeignKey(Author, related_name='book_contact_set') 32 | publisher = models.ForeignKey(Publisher) 33 | pubdate = models.DateField() 34 | 35 | def __str__(self): 36 | return self.name 37 | 38 | @python_2_unicode_compatible 39 | class Store(models.Model): 40 | name = models.CharField(max_length=255) 41 | books = models.ManyToManyField(Book) 42 | original_opening = models.DateTimeField() 43 | friday_night_closing = models.TimeField() 44 | 45 | def __str__(self): 46 | return self.name 47 | 48 | -------------------------------------------------------------------------------- /tests/django20/custom_columns/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 17. Custom column/table names 3 | 4 | If your database column name is different than your model attribute, use the 5 | ``db_column`` parameter. Note that you'll use the field's name, not its column 6 | name, in API usage. 7 | 8 | If your database table name is different than your model name, use the 9 | ``db_table`` Meta attribute. This has no effect on the API used to 10 | query the database. 11 | 12 | If you need to use a table name for a many-to-many relationship that differs 13 | from the default generated name, use the ``db_table`` parameter on the 14 | ``ManyToManyField``. This has no effect on the API for querying the database. 15 | 16 | """ 17 | 18 | from __future__ import unicode_literals 19 | 20 | from django.db import models 21 | from django.utils.encoding import python_2_unicode_compatible 22 | 23 | 24 | @python_2_unicode_compatible 25 | class Author(models.Model): 26 | first_name = models.CharField(max_length=30, db_column='firstname') 27 | last_name = models.CharField(max_length=30, db_column='last') 28 | 29 | def __str__(self): 30 | return '%s %s' % (self.first_name, self.last_name) 31 | 32 | class Meta: 33 | db_table = 'my_author_table' 34 | ordering = ('last_name','first_name') 35 | 36 | @python_2_unicode_compatible 37 | class Article(models.Model): 38 | headline = models.CharField(max_length=100) 39 | authors = models.ManyToManyField(Author, db_table='my_m2m_table') 40 | 41 | def __str__(self): 42 | return self.headline 43 | 44 | class Meta: 45 | ordering = ('headline',) 46 | 47 | -------------------------------------------------------------------------------- /tests/django20/one_to_one_regress/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Place(models.Model): 9 | name = models.CharField(max_length=50) 10 | address = models.CharField(max_length=80) 11 | 12 | def __str__(self): 13 | return "%s the place" % self.name 14 | 15 | @python_2_unicode_compatible 16 | class Restaurant(models.Model): 17 | place = models.OneToOneField(Place) 18 | serves_hot_dogs = models.BooleanField(default=False) 19 | serves_pizza = models.BooleanField(default=False) 20 | 21 | def __str__(self): 22 | return "%s the restaurant" % self.place.name 23 | 24 | @python_2_unicode_compatible 25 | class Bar(models.Model): 26 | place = models.OneToOneField(Place) 27 | serves_cocktails = models.BooleanField(default=True) 28 | 29 | def __str__(self): 30 | return "%s the bar" % self.place.name 31 | 32 | class UndergroundBar(models.Model): 33 | place = models.OneToOneField(Place, null=True) 34 | serves_cocktails = models.BooleanField(default=True) 35 | 36 | @python_2_unicode_compatible 37 | class Favorites(models.Model): 38 | name = models.CharField(max_length = 50) 39 | restaurants = models.ManyToManyField(Restaurant) 40 | 41 | def __str__(self): 42 | return "Favorites for %s" % self.name 43 | 44 | class Target(models.Model): 45 | pass 46 | 47 | class Pointer(models.Model): 48 | other = models.OneToOneField(Target, primary_key=True) 49 | 50 | class Pointer2(models.Model): 51 | other = models.OneToOneField(Target) 52 | -------------------------------------------------------------------------------- /tests/django20/reverse_single_related/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import Source, Item 6 | 7 | 8 | class ReverseSingleRelatedTests(TestCase): 9 | """ 10 | Regression tests for an object that cannot access a single related 11 | object due to a restrictive default manager. 12 | """ 13 | 14 | def test_reverse_single_related(self): 15 | 16 | public_source = Source.objects.create(is_public=True) 17 | public_item = Item.objects.create(source=public_source) 18 | 19 | private_source = Source.objects.create(is_public=False) 20 | private_item = Item.objects.create(source=private_source) 21 | 22 | # Only one source is available via all() due to the custom default manager. 23 | self.assertQuerysetEqual( 24 | Source.objects.all(), 25 | [""] 26 | ) 27 | 28 | self.assertEqual(public_item.source, public_source) 29 | 30 | # Make sure that an item can still access its related source even if the default 31 | # manager doesn't normally allow it. 32 | self.assertEqual(private_item.source, private_source) 33 | 34 | # If the manager is marked "use_for_related_fields", it'll get used instead 35 | # of the "bare" queryset. Usually you'd define this as a property on the class, 36 | # but this approximates that in a way that's easier in tests. 37 | Source.objects.use_for_related_fields = True 38 | private_item = Item.objects.get(pk=private_item.pk) 39 | self.assertRaises(Source.DoesNotExist, lambda: private_item.source) 40 | -------------------------------------------------------------------------------- /tests/django20/model_inheritance_same_model_name/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from model_inheritance.models import Title 6 | 7 | 8 | class InheritanceSameModelNameTests(TestCase): 9 | 10 | def setUp(self): 11 | # The Title model has distinct accessors for both 12 | # model_inheritance.Copy and model_inheritance_same_model_name.Copy 13 | # models. 14 | self.title = Title.objects.create(title='Lorem Ipsum') 15 | 16 | def test_inheritance_related_name(self): 17 | from model_inheritance.models import Copy 18 | self.assertEqual( 19 | self.title.attached_model_inheritance_copy_set.create( 20 | content='Save $ on V1agr@', 21 | url='http://v1agra.com/', 22 | title='V1agra is spam', 23 | ), Copy.objects.get(content='Save $ on V1agr@')) 24 | 25 | def test_inheritance_with_same_model_name(self): 26 | from model_inheritance_same_model_name.models import Copy 27 | self.assertEqual( 28 | self.title.attached_model_inheritance_same_model_name_copy_set.create( 29 | content='The Web framework for perfectionists with deadlines.', 30 | url='http://www.djangoproject.com/', 31 | title='Django Rocks' 32 | ), Copy.objects.get(content='The Web framework for perfectionists with deadlines.')) 33 | 34 | def test_related_name_attribute_exists(self): 35 | # The Post model doesn't have an attribute called 'attached_%(app_label)s_%(class)s_set'. 36 | self.assertEqual(hasattr(self.title, 'attached_%(app_label)s_%(class)s_set'), False) 37 | -------------------------------------------------------------------------------- /tests/django20/string_lookup/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | from django.utils.encoding import python_2_unicode_compatible 6 | 7 | 8 | @python_2_unicode_compatible 9 | class Foo(models.Model): 10 | name = models.CharField(max_length=50) 11 | friend = models.CharField(max_length=50, blank=True) 12 | 13 | def __str__(self): 14 | return "Foo %s" % self.name 15 | 16 | @python_2_unicode_compatible 17 | class Bar(models.Model): 18 | name = models.CharField(max_length=50) 19 | normal = models.ForeignKey(Foo, related_name='normal_foo') 20 | fwd = models.ForeignKey("Whiz") 21 | back = models.ForeignKey("Foo") 22 | 23 | def __str__(self): 24 | return "Bar %s" % self.place.name 25 | 26 | @python_2_unicode_compatible 27 | class Whiz(models.Model): 28 | name = models.CharField(max_length=50) 29 | 30 | def __str__(self): 31 | return "Whiz %s" % self.name 32 | 33 | @python_2_unicode_compatible 34 | class Child(models.Model): 35 | parent = models.OneToOneField('Base') 36 | name = models.CharField(max_length=50) 37 | 38 | def __str__(self): 39 | return "Child %s" % self.name 40 | 41 | @python_2_unicode_compatible 42 | class Base(models.Model): 43 | name = models.CharField(max_length=50) 44 | 45 | def __str__(self): 46 | return "Base %s" % self.name 47 | 48 | @python_2_unicode_compatible 49 | class Article(models.Model): 50 | name = models.CharField(max_length=50) 51 | text = models.TextField() 52 | submitted_from = models.IPAddressField(blank=True, null=True) 53 | 54 | def __str__(self): 55 | return "Article %s" % self.name 56 | -------------------------------------------------------------------------------- /tests/django20/max_lengths/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.utils import unittest 4 | 5 | from .models import PersonWithDefaultMaxLengths, PersonWithCustomMaxLengths 6 | 7 | 8 | class MaxLengthArgumentsTests(unittest.TestCase): 9 | 10 | def verify_max_length(self, model,field,length): 11 | self.assertEqual(model._meta.get_field(field).max_length,length) 12 | 13 | def test_default_max_lengths(self): 14 | self.verify_max_length(PersonWithDefaultMaxLengths, 'email', 75) 15 | self.verify_max_length(PersonWithDefaultMaxLengths, 'vcard', 100) 16 | self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200) 17 | self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100) 18 | 19 | def test_custom_max_lengths(self): 20 | self.verify_max_length(PersonWithCustomMaxLengths, 'email', 250) 21 | self.verify_max_length(PersonWithCustomMaxLengths, 'vcard', 250) 22 | self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 250) 23 | self.verify_max_length(PersonWithCustomMaxLengths, 'avatar', 250) 24 | 25 | class MaxLengthORMTests(unittest.TestCase): 26 | 27 | def test_custom_max_lengths(self): 28 | args = { 29 | "email": "someone@example.com", 30 | "vcard": "vcard", 31 | "homepage": "http://example.com/", 32 | "avatar": "me.jpg" 33 | } 34 | 35 | for field in ("email", "vcard", "homepage", "avatar"): 36 | new_args = args.copy() 37 | new_args[field] = "X" * 250 # a value longer than any of the default fields could hold. 38 | p = PersonWithCustomMaxLengths.objects.create(**new_args) 39 | self.assertEqual(getattr(p, field), ("X" * 250)) -------------------------------------------------------------------------------- /tests/django20/null_fk_ordering/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for proper working of ForeignKey(null=True). Tests these bugs: 3 | 4 | * #7512: including a nullable foreign key reference in Meta ordering has un 5 | xpected results 6 | 7 | """ 8 | from __future__ import unicode_literals 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | # The first two models represent a very simple null FK ordering case. 15 | class Author(models.Model): 16 | name = models.CharField(max_length=150) 17 | 18 | @python_2_unicode_compatible 19 | class Article(models.Model): 20 | title = models.CharField(max_length=150) 21 | author = models.ForeignKey(Author, null=True) 22 | 23 | def __str__(self): 24 | return 'Article titled: %s' % (self.title, ) 25 | 26 | class Meta: 27 | ordering = ['author__name', ] 28 | 29 | 30 | # These following 4 models represent a far more complex ordering case. 31 | class SystemInfo(models.Model): 32 | system_name = models.CharField(max_length=32) 33 | 34 | class Forum(models.Model): 35 | system_info = models.ForeignKey(SystemInfo) 36 | forum_name = models.CharField(max_length=32) 37 | 38 | @python_2_unicode_compatible 39 | class Post(models.Model): 40 | forum = models.ForeignKey(Forum, null=True) 41 | title = models.CharField(max_length=32) 42 | 43 | def __str__(self): 44 | return self.title 45 | 46 | @python_2_unicode_compatible 47 | class Comment(models.Model): 48 | post = models.ForeignKey(Post, null=True) 49 | comment_text = models.CharField(max_length=250) 50 | 51 | class Meta: 52 | ordering = ['post__forum__system_info__system_name', 'comment_text'] 53 | 54 | def __str__(self): 55 | return self.comment_text 56 | -------------------------------------------------------------------------------- /tests/django20/lookup/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 7. The lookup API 3 | 4 | This demonstrates features of the database API. 5 | """ 6 | 7 | from __future__ import unicode_literals 8 | 9 | from django.db import models 10 | from django.utils import six 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | class Author(models.Model): 15 | name = models.CharField(max_length=100) 16 | class Meta: 17 | ordering = ('name', ) 18 | 19 | @python_2_unicode_compatible 20 | class Article(models.Model): 21 | headline = models.CharField(max_length=100) 22 | pub_date = models.DateTimeField() 23 | author = models.ForeignKey(Author, blank=True, null=True) 24 | class Meta: 25 | ordering = ('-pub_date', 'headline') 26 | 27 | def __str__(self): 28 | return self.headline 29 | 30 | class Tag(models.Model): 31 | articles = models.ManyToManyField(Article) 32 | name = models.CharField(max_length=100) 33 | class Meta: 34 | ordering = ('name', ) 35 | 36 | @python_2_unicode_compatible 37 | class Season(models.Model): 38 | year = models.PositiveSmallIntegerField() 39 | gt = models.IntegerField(null=True, blank=True) 40 | 41 | def __str__(self): 42 | return six.text_type(self.year) 43 | 44 | @python_2_unicode_compatible 45 | class Game(models.Model): 46 | season = models.ForeignKey(Season, related_name='games') 47 | home = models.CharField(max_length=100) 48 | away = models.CharField(max_length=100) 49 | 50 | def __str__(self): 51 | return "%s at %s" % (self.away, self.home) 52 | 53 | @python_2_unicode_compatible 54 | class Player(models.Model): 55 | name = models.CharField(max_length=100) 56 | games = models.ManyToManyField(Game, related_name='players') 57 | 58 | def __str__(self): 59 | return self.name 60 | -------------------------------------------------------------------------------- /tests/django20/initial_sql_regress/tests.py: -------------------------------------------------------------------------------- 1 | from django.core.management.color import no_style 2 | from django.core.management.sql import custom_sql_for_model 3 | from django.db import connections, DEFAULT_DB_ALIAS 4 | from django.test import TestCase 5 | from django.test.utils import override_settings 6 | 7 | from .models import Simple 8 | 9 | 10 | class InitialSQLTests(TestCase): 11 | """ 12 | The format of the included SQL file for this test suite is important. 13 | It must end with a trailing newline in order to test the fix for #2161. 14 | """ 15 | 16 | def test_initial_sql(self): 17 | """ 18 | As pointed out by #14661, test data loaded by custom SQL 19 | can't be relied upon; as a result, the test framework flushes the 20 | data contents before every test. This test validates that this has 21 | occurred. 22 | """ 23 | self.assertEqual(Simple.objects.count(), 0) 24 | 25 | def test_custom_sql(self): 26 | """ 27 | Simulate the custom SQL loading by syncdb. 28 | """ 29 | connection = connections[DEFAULT_DB_ALIAS] 30 | custom_sql = custom_sql_for_model(Simple, no_style(), connection) 31 | self.assertEqual(len(custom_sql), 9) 32 | cursor = connection.cursor() 33 | for sql in custom_sql: 34 | cursor.execute(sql) 35 | self.assertEqual(Simple.objects.count(), 9) 36 | self.assertEqual( 37 | Simple.objects.get(name__contains='placeholders').name, 38 | '"100%" of % are not placeholders' 39 | ) 40 | 41 | @override_settings(DEBUG=True) 42 | def test_custom_sql_debug(self): 43 | """ 44 | Same test, ensure that CursorDebugWrapper doesn't alter sql loading 45 | (#3485). 46 | """ 47 | self.test_custom_sql() 48 | -------------------------------------------------------------------------------- /tests/django20/one_to_one/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 10. One-to-one relationships 3 | 4 | To define a one-to-one relationship, use ``OneToOneField()``. 5 | 6 | In this example, a ``Place`` optionally can be a ``Restaurant``. 7 | """ 8 | from __future__ import unicode_literals 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | 14 | @python_2_unicode_compatible 15 | class Place(models.Model): 16 | name = models.CharField(max_length=50) 17 | address = models.CharField(max_length=80) 18 | 19 | def __str__(self): 20 | return "%s the place" % self.name 21 | 22 | @python_2_unicode_compatible 23 | class Restaurant(models.Model): 24 | place = models.OneToOneField(Place, primary_key=True) 25 | serves_hot_dogs = models.BooleanField(default=False) 26 | serves_pizza = models.BooleanField(default=False) 27 | 28 | def __str__(self): 29 | return "%s the restaurant" % self.place.name 30 | 31 | @python_2_unicode_compatible 32 | class Waiter(models.Model): 33 | restaurant = models.ForeignKey(Restaurant) 34 | name = models.CharField(max_length=50) 35 | 36 | def __str__(self): 37 | return "%s the waiter at %s" % (self.name, self.restaurant) 38 | 39 | class ManualPrimaryKey(models.Model): 40 | primary_key = models.CharField(max_length=10, primary_key=True) 41 | name = models.CharField(max_length = 50) 42 | 43 | class RelatedModel(models.Model): 44 | link = models.OneToOneField(ManualPrimaryKey) 45 | name = models.CharField(max_length = 50) 46 | 47 | @python_2_unicode_compatible 48 | class MultiModel(models.Model): 49 | link1 = models.OneToOneField(Place) 50 | link2 = models.OneToOneField(ManualPrimaryKey) 51 | name = models.CharField(max_length=50) 52 | 53 | def __str__(self): 54 | return "Multimodel %s" % self.name 55 | -------------------------------------------------------------------------------- /django_pyodbc/metadata.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008, django-pyodbc developers (see README.rst). 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of django-sql-server nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | __version__ = "2.0.0a2" 30 | __maintainer__ = "Dan Loewenherz" 31 | __maintainer_email__ = "dan@lionheartsw.com" 32 | __license__ = "BSD 3-Clause License" 33 | 34 | -------------------------------------------------------------------------------- /tests/django20/custom_pk/fields.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | 4 | from django.db import models 5 | from django.utils import six 6 | from django.utils.encoding import python_2_unicode_compatible 7 | 8 | 9 | @python_2_unicode_compatible 10 | class MyWrapper(object): 11 | def __init__(self, value): 12 | self.value = value 13 | 14 | def __repr__(self): 15 | return "<%s: %s>" % (self.__class__.__name__, self.value) 16 | 17 | def __str__(self): 18 | return self.value 19 | 20 | def __eq__(self, other): 21 | if isinstance(other, self.__class__): 22 | return self.value == other.value 23 | return self.value == other 24 | 25 | class MyAutoField(six.with_metaclass(models.SubfieldBase, models.CharField)): 26 | 27 | def __init__(self, *args, **kwargs): 28 | kwargs['max_length'] = 10 29 | super(MyAutoField, self).__init__(*args, **kwargs) 30 | 31 | def pre_save(self, instance, add): 32 | value = getattr(instance, self.attname, None) 33 | if not value: 34 | value = MyWrapper(''.join(random.sample(string.ascii_lowercase, 10))) 35 | setattr(instance, self.attname, value) 36 | return value 37 | 38 | def to_python(self, value): 39 | if not value: 40 | return 41 | if not isinstance(value, MyWrapper): 42 | value = MyWrapper(value) 43 | return value 44 | 45 | def get_db_prep_save(self, value, connection): 46 | if not value: 47 | return 48 | if isinstance(value, MyWrapper): 49 | return six.text_type(value) 50 | return value 51 | 52 | def get_db_prep_value(self, value, connection, prepared=False): 53 | if not value: 54 | return 55 | if isinstance(value, MyWrapper): 56 | return six.text_type(value) 57 | return value 58 | -------------------------------------------------------------------------------- /tests/django20/m2o_recursive/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import Category, Person 6 | 7 | 8 | class ManyToOneRecursiveTests(TestCase): 9 | 10 | def setUp(self): 11 | self.r = Category(id=None, name='Root category', parent=None) 12 | self.r.save() 13 | self.c = Category(id=None, name='Child category', parent=self.r) 14 | self.c.save() 15 | 16 | def test_m2o_recursive(self): 17 | self.assertQuerysetEqual(self.r.child_set.all(), 18 | ['']) 19 | self.assertEqual(self.r.child_set.get(name__startswith='Child').id, self.c.id) 20 | self.assertEqual(self.r.parent, None) 21 | self.assertQuerysetEqual(self.c.child_set.all(), []) 22 | self.assertEqual(self.c.parent.id, self.r.id) 23 | 24 | class MultipleManyToOneRecursiveTests(TestCase): 25 | 26 | def setUp(self): 27 | self.dad = Person(full_name='John Smith Senior', mother=None, father=None) 28 | self.dad.save() 29 | self.mom = Person(full_name='Jane Smith', mother=None, father=None) 30 | self.mom.save() 31 | self.kid = Person(full_name='John Smith Junior', mother=self.mom, father=self.dad) 32 | self.kid.save() 33 | 34 | def test_m2o_recursive2(self): 35 | self.assertEqual(self.kid.mother.id, self.mom.id) 36 | self.assertEqual(self.kid.father.id, self.dad.id) 37 | self.assertQuerysetEqual(self.dad.fathers_child_set.all(), 38 | ['']) 39 | self.assertQuerysetEqual(self.mom.mothers_child_set.all(), 40 | ['']) 41 | self.assertQuerysetEqual(self.kid.mothers_child_set.all(), []) 42 | self.assertQuerysetEqual(self.kid.fathers_child_set.all(), []) 43 | -------------------------------------------------------------------------------- /tests/django20/reserved_names/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import datetime 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Thing 8 | 9 | 10 | class ReservedNameTests(TestCase): 11 | def generate(self): 12 | day1 = datetime.date(2005, 1, 1) 13 | t = Thing.objects.create(when='a', join='b', like='c', drop='d', 14 | alter='e', having='f', where=day1, has_hyphen='h') 15 | day2 = datetime.date(2006, 2, 2) 16 | u = Thing.objects.create(when='h', join='i', like='j', drop='k', 17 | alter='l', having='m', where=day2) 18 | 19 | def test_simple(self): 20 | day1 = datetime.date(2005, 1, 1) 21 | t = Thing.objects.create(when='a', join='b', like='c', drop='d', 22 | alter='e', having='f', where=day1, has_hyphen='h') 23 | self.assertEqual(t.when, 'a') 24 | 25 | day2 = datetime.date(2006, 2, 2) 26 | u = Thing.objects.create(when='h', join='i', like='j', drop='k', 27 | alter='l', having='m', where=day2) 28 | self.assertEqual(u.when, 'h') 29 | 30 | def test_order_by(self): 31 | self.generate() 32 | things = [t.when for t in Thing.objects.order_by('when')] 33 | self.assertEqual(things, ['a', 'h']) 34 | 35 | def test_fields(self): 36 | self.generate() 37 | v = Thing.objects.get(pk='a') 38 | self.assertEqual(v.join, 'b') 39 | self.assertEqual(v.where, datetime.date(year=2005, month=1, day=1)) 40 | 41 | def test_dates(self): 42 | self.generate() 43 | resp = Thing.objects.dates('where', 'year') 44 | self.assertEqual(list(resp), [ 45 | datetime.date(2005, 1, 1), 46 | datetime.date(2006, 1, 1), 47 | ]) 48 | 49 | def test_month_filter(self): 50 | self.generate() 51 | self.assertEqual(Thing.objects.filter(where__month=1)[0].when, 'a') 52 | -------------------------------------------------------------------------------- /tests/django20/reverse_lookup/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.core.exceptions import FieldError 4 | from django.test import TestCase 5 | 6 | from .models import User, Poll, Choice 7 | 8 | 9 | class ReverseLookupTests(TestCase): 10 | 11 | def setUp(self): 12 | john = User.objects.create(name="John Doe") 13 | jim = User.objects.create(name="Jim Bo") 14 | first_poll = Poll.objects.create( 15 | question="What's the first question?", 16 | creator=john 17 | ) 18 | second_poll = Poll.objects.create( 19 | question="What's the second question?", 20 | creator=jim 21 | ) 22 | new_choice = Choice.objects.create( 23 | poll=first_poll, 24 | related_poll=second_poll, 25 | name="This is the answer." 26 | ) 27 | 28 | def test_reverse_by_field(self): 29 | u1 = User.objects.get( 30 | poll__question__exact="What's the first question?" 31 | ) 32 | self.assertEqual(u1.name, "John Doe") 33 | 34 | u2 = User.objects.get( 35 | poll__question__exact="What's the second question?" 36 | ) 37 | self.assertEqual(u2.name, "Jim Bo") 38 | 39 | def test_reverse_by_related_name(self): 40 | p1 = Poll.objects.get(poll_choice__name__exact="This is the answer.") 41 | self.assertEqual(p1.question, "What's the first question?") 42 | 43 | p2 = Poll.objects.get( 44 | related_choice__name__exact="This is the answer.") 45 | self.assertEqual(p2.question, "What's the second question?") 46 | 47 | def test_reverse_field_name_disallowed(self): 48 | """ 49 | If a related_name is given you can't use the field name instead 50 | """ 51 | self.assertRaises(FieldError, Poll.objects.get, 52 | choice__name__exact="This is the answer") 53 | -------------------------------------------------------------------------------- /tests/django20/known_related_objects/fixtures/tournament.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "known_related_objects.tournament", 5 | "fields": { 6 | "name": "Tourney 1" 7 | } 8 | }, 9 | { 10 | "pk": 2, 11 | "model": "known_related_objects.tournament", 12 | "fields": { 13 | "name": "Tourney 2" 14 | } 15 | }, 16 | { 17 | "pk": 1, 18 | "model": "known_related_objects.organiser", 19 | "fields": { 20 | "name": "Organiser 1" 21 | } 22 | }, 23 | { 24 | "pk": 1, 25 | "model": "known_related_objects.pool", 26 | "fields": { 27 | "tournament": 1, 28 | "organiser": 1, 29 | "name": "T1 Pool 1" 30 | } 31 | }, 32 | { 33 | "pk": 2, 34 | "model": "known_related_objects.pool", 35 | "fields": { 36 | "tournament": 1, 37 | "organiser": 1, 38 | "name": "T1 Pool 2" 39 | } 40 | }, 41 | { 42 | "pk": 3, 43 | "model": "known_related_objects.pool", 44 | "fields": { 45 | "tournament": 2, 46 | "organiser": 1, 47 | "name": "T2 Pool 1" 48 | } 49 | }, 50 | { 51 | "pk": 4, 52 | "model": "known_related_objects.pool", 53 | "fields": { 54 | "tournament": 2, 55 | "organiser": 1, 56 | "name": "T2 Pool 2" 57 | } 58 | }, 59 | { 60 | "pk": 1, 61 | "model": "known_related_objects.poolstyle", 62 | "fields": { 63 | "name": "T1 Pool 2 Style", 64 | "pool": 2 65 | } 66 | }, 67 | { 68 | "pk": 2, 69 | "model": "known_related_objects.poolstyle", 70 | "fields": { 71 | "name": "T2 Pool 1 Style", 72 | "pool": 3 73 | } 74 | } 75 | ] 76 | 77 | -------------------------------------------------------------------------------- /tests/django20/tablespaces/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Since the test database doesn't have tablespaces, it's impossible for Django 4 | # to create the tables for models where db_tablespace is set. To avoid this 5 | # problem, we mark the models as unmanaged, and temporarily revert them to 6 | # managed during each test. We also set them to use the same tables as the 7 | # "reference" models to avoid errors when other tests run 'syncdb' 8 | # (proxy_models_inheritance does). 9 | 10 | class ScientistRef(models.Model): 11 | name = models.CharField(max_length=50) 12 | 13 | class ArticleRef(models.Model): 14 | title = models.CharField(max_length=50, unique=True) 15 | code = models.CharField(max_length=50, unique=True) 16 | authors = models.ManyToManyField(ScientistRef, related_name='articles_written_set') 17 | reviewers = models.ManyToManyField(ScientistRef, related_name='articles_reviewed_set') 18 | 19 | class Scientist(models.Model): 20 | name = models.CharField(max_length=50) 21 | class Meta: 22 | db_table = 'tablespaces_scientistref' 23 | db_tablespace = 'tbl_tbsp' 24 | managed = False 25 | 26 | class Article(models.Model): 27 | title = models.CharField(max_length=50, unique=True) 28 | code = models.CharField(max_length=50, unique=True, db_tablespace='idx_tbsp') 29 | authors = models.ManyToManyField(Scientist, related_name='articles_written_set') 30 | reviewers = models.ManyToManyField(Scientist, related_name='articles_reviewed_set', db_tablespace='idx_tbsp') 31 | class Meta: 32 | db_table = 'tablespaces_articleref' 33 | db_tablespace = 'tbl_tbsp' 34 | managed = False 35 | 36 | # Also set the tables for automatically created models 37 | 38 | Authors = Article._meta.get_field('authors').rel.through 39 | Authors._meta.db_table = 'tablespaces_articleref_authors' 40 | 41 | Reviewers = Article._meta.get_field('reviewers').rel.through 42 | Reviewers._meta.db_table = 'tablespaces_articleref_reviewers' 43 | -------------------------------------------------------------------------------- /tests/django20/many_to_one_regress/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for a few ForeignKey bugs. 3 | """ 4 | from __future__ import unicode_literals 5 | 6 | from django.db import models 7 | from django.utils.encoding import python_2_unicode_compatible 8 | 9 | # If ticket #1578 ever slips back in, these models will not be able to be 10 | # created (the field names being lower-cased versions of their opposite 11 | # classes is important here). 12 | 13 | class First(models.Model): 14 | second = models.IntegerField() 15 | 16 | class Second(models.Model): 17 | first = models.ForeignKey(First, related_name = 'the_first') 18 | 19 | # Protect against repetition of #1839, #2415 and #2536. 20 | class Third(models.Model): 21 | name = models.CharField(max_length=20) 22 | third = models.ForeignKey('self', null=True, related_name='child_set') 23 | 24 | class Parent(models.Model): 25 | name = models.CharField(max_length=20) 26 | bestchild = models.ForeignKey('Child', null=True, related_name='favored_by') 27 | 28 | class Child(models.Model): 29 | name = models.CharField(max_length=20) 30 | parent = models.ForeignKey(Parent) 31 | 32 | 33 | # Multiple paths to the same model (#7110, #7125) 34 | @python_2_unicode_compatible 35 | class Category(models.Model): 36 | name = models.CharField(max_length=20) 37 | 38 | def __str__(self): 39 | return self.name 40 | 41 | class Record(models.Model): 42 | category = models.ForeignKey(Category) 43 | 44 | @python_2_unicode_compatible 45 | class Relation(models.Model): 46 | left = models.ForeignKey(Record, related_name='left_set') 47 | right = models.ForeignKey(Record, related_name='right_set') 48 | 49 | def __str__(self): 50 | return "%s - %s" % (self.left.category.name, self.right.category.name) 51 | 52 | class Car(models.Model): 53 | make = models.CharField(max_length=100, null=True, unique=True) 54 | 55 | class Driver(models.Model): 56 | car = models.ForeignKey(Car, to_field='make', null=True, related_name='drivers') 57 | -------------------------------------------------------------------------------- /tests/django20/select_related/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 41. Tests for select_related() 3 | 4 | ``select_related()`` follows all relationships and pre-caches any foreign key 5 | values so that complex trees can be fetched in a single query. However, this 6 | isn't always a good idea, so the ``depth`` argument control how many "levels" 7 | the select-related behavior will traverse. 8 | """ 9 | 10 | from django.db import models 11 | from django.utils.encoding import python_2_unicode_compatible 12 | 13 | # Who remembers high school biology? 14 | 15 | @python_2_unicode_compatible 16 | class Domain(models.Model): 17 | name = models.CharField(max_length=50) 18 | def __str__(self): 19 | return self.name 20 | 21 | @python_2_unicode_compatible 22 | class Kingdom(models.Model): 23 | name = models.CharField(max_length=50) 24 | domain = models.ForeignKey(Domain) 25 | def __str__(self): 26 | return self.name 27 | 28 | @python_2_unicode_compatible 29 | class Phylum(models.Model): 30 | name = models.CharField(max_length=50) 31 | kingdom = models.ForeignKey(Kingdom) 32 | def __str__(self): 33 | return self.name 34 | 35 | @python_2_unicode_compatible 36 | class Klass(models.Model): 37 | name = models.CharField(max_length=50) 38 | phylum = models.ForeignKey(Phylum) 39 | def __str__(self): 40 | return self.name 41 | 42 | @python_2_unicode_compatible 43 | class Order(models.Model): 44 | name = models.CharField(max_length=50) 45 | klass = models.ForeignKey(Klass) 46 | def __str__(self): 47 | return self.name 48 | 49 | @python_2_unicode_compatible 50 | class Family(models.Model): 51 | name = models.CharField(max_length=50) 52 | order = models.ForeignKey(Order) 53 | def __str__(self): 54 | return self.name 55 | 56 | @python_2_unicode_compatible 57 | class Genus(models.Model): 58 | name = models.CharField(max_length=50) 59 | family = models.ForeignKey(Family) 60 | def __str__(self): 61 | return self.name 62 | 63 | @python_2_unicode_compatible 64 | class Species(models.Model): 65 | name = models.CharField(max_length=50) 66 | genus = models.ForeignKey(Genus) 67 | def __str__(self): 68 | return self.name 69 | -------------------------------------------------------------------------------- /tests/django20/null_fk_ordering/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import Author, Article, SystemInfo, Forum, Post, Comment 6 | 7 | 8 | class NullFkOrderingTests(TestCase): 9 | 10 | def test_ordering_across_null_fk(self): 11 | """ 12 | Regression test for #7512 13 | 14 | ordering across nullable Foreign Keys shouldn't exclude results 15 | """ 16 | author_1 = Author.objects.create(name='Tom Jones') 17 | author_2 = Author.objects.create(name='Bob Smith') 18 | article_1 = Article.objects.create(title='No author on this article') 19 | article_2 = Article.objects.create(author=author_1, title='This article written by Tom Jones') 20 | article_3 = Article.objects.create(author=author_2, title='This article written by Bob Smith') 21 | 22 | # We can't compare results directly (since different databases sort NULLs to 23 | # different ends of the ordering), but we can check that all results are 24 | # returned. 25 | self.assertTrue(len(list(Article.objects.all())) == 3) 26 | 27 | s = SystemInfo.objects.create(system_name='System Info') 28 | f = Forum.objects.create(system_info=s, forum_name='First forum') 29 | p = Post.objects.create(forum=f, title='First Post') 30 | c1 = Comment.objects.create(post=p, comment_text='My first comment') 31 | c2 = Comment.objects.create(comment_text='My second comment') 32 | s2 = SystemInfo.objects.create(system_name='More System Info') 33 | f2 = Forum.objects.create(system_info=s2, forum_name='Second forum') 34 | p2 = Post.objects.create(forum=f2, title='Second Post') 35 | c3 = Comment.objects.create(comment_text='Another first comment') 36 | c4 = Comment.objects.create(post=p2, comment_text='Another second comment') 37 | 38 | # We have to test this carefully. Some databases sort NULL values before 39 | # everything else, some sort them afterwards. So we extract the ordered list 40 | # and check the length. Before the fix, this list was too short (some values 41 | # were omitted). 42 | self.assertTrue(len(list(Comment.objects.all())) == 4) 43 | -------------------------------------------------------------------------------- /tests/django20/custom_managers/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | 23. Giving models a custom manager 3 | 4 | You can use a custom ``Manager`` in a particular model by extending the base 5 | ``Manager`` class and instantiating your custom ``Manager`` in your model. 6 | 7 | There are two reasons you might want to customize a ``Manager``: to add extra 8 | ``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager`` 9 | returns. 10 | """ 11 | 12 | from __future__ import unicode_literals 13 | 14 | from django.db import models 15 | from django.utils.encoding import python_2_unicode_compatible 16 | 17 | # An example of a custom manager called "objects". 18 | 19 | class PersonManager(models.Manager): 20 | def get_fun_people(self): 21 | return self.filter(fun=True) 22 | 23 | @python_2_unicode_compatible 24 | class Person(models.Model): 25 | first_name = models.CharField(max_length=30) 26 | last_name = models.CharField(max_length=30) 27 | fun = models.BooleanField(default=False) 28 | objects = PersonManager() 29 | 30 | def __str__(self): 31 | return "%s %s" % (self.first_name, self.last_name) 32 | 33 | # An example of a custom manager that sets get_queryset(). 34 | 35 | class PublishedBookManager(models.Manager): 36 | def get_queryset(self): 37 | return super(PublishedBookManager, self).get_queryset().filter(is_published=True) 38 | 39 | @python_2_unicode_compatible 40 | class Book(models.Model): 41 | title = models.CharField(max_length=50) 42 | author = models.CharField(max_length=30) 43 | is_published = models.BooleanField(default=False) 44 | published_objects = PublishedBookManager() 45 | authors = models.ManyToManyField(Person, related_name='books') 46 | 47 | def __str__(self): 48 | return self.title 49 | 50 | # An example of providing multiple custom managers. 51 | 52 | class FastCarManager(models.Manager): 53 | def get_queryset(self): 54 | return super(FastCarManager, self).get_queryset().filter(top_speed__gt=150) 55 | 56 | @python_2_unicode_compatible 57 | class Car(models.Model): 58 | name = models.CharField(max_length=10) 59 | mileage = models.IntegerField() 60 | top_speed = models.IntegerField(help_text="In miles per hour.") 61 | cars = models.Manager() 62 | fast_cars = FastCarManager() 63 | 64 | def __str__(self): 65 | return self.name 66 | -------------------------------------------------------------------------------- /tests/django20/custom_managers_regress/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import RelatedModel, RestrictedModel, OneToOneRestrictedModel 6 | 7 | 8 | class CustomManagersRegressTestCase(TestCase): 9 | def test_filtered_default_manager(self): 10 | """Even though the default manager filters out some records, 11 | we must still be able to save (particularly, save by updating 12 | existing records) those filtered instances. This is a 13 | regression test for #8990, #9527""" 14 | related = RelatedModel.objects.create(name="xyzzy") 15 | obj = RestrictedModel.objects.create(name="hidden", related=related) 16 | obj.name = "still hidden" 17 | obj.save() 18 | 19 | # If the hidden object wasn't seen during the save process, 20 | # there would now be two objects in the database. 21 | self.assertEqual(RestrictedModel.plain_manager.count(), 1) 22 | 23 | def test_delete_related_on_filtered_manager(self): 24 | """Deleting related objects should also not be distracted by a 25 | restricted manager on the related object. This is a regression 26 | test for #2698.""" 27 | related = RelatedModel.objects.create(name="xyzzy") 28 | 29 | for name, public in (('one', True), ('two', False), ('three', False)): 30 | RestrictedModel.objects.create(name=name, is_public=public, related=related) 31 | 32 | obj = RelatedModel.objects.get(name="xyzzy") 33 | obj.delete() 34 | 35 | # All of the RestrictedModel instances should have been 36 | # deleted, since they *all* pointed to the RelatedModel. If 37 | # the default manager is used, only the public one will be 38 | # deleted. 39 | self.assertEqual(len(RestrictedModel.plain_manager.all()), 0) 40 | 41 | def test_delete_one_to_one_manager(self): 42 | # The same test case as the last one, but for one-to-one 43 | # models, which are implemented slightly different internally, 44 | # so it's a different code path. 45 | obj = RelatedModel.objects.create(name="xyzzy") 46 | OneToOneRestrictedModel.objects.create(name="foo", is_public=False, related=obj) 47 | obj = RelatedModel.objects.get(name="xyzzy") 48 | obj.delete() 49 | self.assertEqual(len(OneToOneRestrictedModel.plain_manager.all()), 0) 50 | 51 | -------------------------------------------------------------------------------- /tests/django20/custom_columns/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.core.exceptions import FieldError 4 | from django.test import TestCase 5 | from django.utils import six 6 | 7 | from .models import Author, Article 8 | 9 | 10 | class CustomColumnsTests(TestCase): 11 | def setUp(self): 12 | a1 = Author.objects.create(first_name="John", last_name="Smith") 13 | a2 = Author.objects.create(first_name="Peter", last_name="Jones") 14 | 15 | art = Article.objects.create(headline="Django lets you build Web apps easily") 16 | art.authors = [a1, a2] 17 | 18 | self.a1 = a1 19 | self.art = art 20 | 21 | def test_query_all_available_authors(self): 22 | self.assertQuerysetEqual( 23 | Author.objects.all(), [ 24 | "Peter Jones", "John Smith", 25 | ], 26 | six.text_type 27 | ) 28 | 29 | def test_get_first_name(self): 30 | self.assertEqual( 31 | Author.objects.get(first_name__exact="John"), 32 | self.a1, 33 | ) 34 | 35 | def test_filter_first_name(self): 36 | self.assertQuerysetEqual( 37 | Author.objects.filter(first_name__exact="John"), [ 38 | "John Smith", 39 | ], 40 | six.text_type 41 | 42 | ) 43 | 44 | def test_field_error(self): 45 | self.assertRaises(FieldError, 46 | lambda: Author.objects.filter(firstname__exact="John") 47 | ) 48 | 49 | def test_attribute_error(self): 50 | with self.assertRaises(AttributeError): 51 | self.a1.firstname 52 | 53 | with self.assertRaises(AttributeError): 54 | self.a1.last 55 | 56 | def test_get_all_authors_for_an_article(self): 57 | self.assertQuerysetEqual( 58 | self.art.authors.all(), [ 59 | "Peter Jones", 60 | "John Smith", 61 | ], 62 | six.text_type 63 | ) 64 | 65 | def test_get_all_articles_for_an_author(self): 66 | self.assertQuerysetEqual( 67 | self.a1.article_set.all(), [ 68 | "Django lets you build Web apps easily", 69 | ], 70 | lambda a: a.headline 71 | ) 72 | 73 | def test_get_author_m2m_relation(self): 74 | self.assertQuerysetEqual( 75 | self.art.authors.filter(last_name='Jones'), [ 76 | "Peter Jones" 77 | ], 78 | six.text_type 79 | ) 80 | -------------------------------------------------------------------------------- /tests/django20/force_insert_update/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.db import transaction, IntegrityError, DatabaseError 4 | from django.test import TestCase 5 | 6 | from .models import (Counter, WithCustomPK, InheritedCounter, ProxyCounter, 7 | SubCounter) 8 | 9 | 10 | class ForceTests(TestCase): 11 | def test_force_update(self): 12 | c = Counter.objects.create(name="one", value=1) 13 | 14 | # The normal case 15 | c.value = 2 16 | c.save() 17 | # Same thing, via an update 18 | c.value = 3 19 | c.save(force_update=True) 20 | 21 | # Won't work because force_update and force_insert are mutually 22 | # exclusive 23 | c.value = 4 24 | with self.assertRaises(ValueError): 25 | c.save(force_insert=True, force_update=True) 26 | 27 | # Try to update something that doesn't have a primary key in the first 28 | # place. 29 | c1 = Counter(name="two", value=2) 30 | with self.assertRaises(ValueError): 31 | with transaction.atomic(): 32 | c1.save(force_update=True) 33 | c1.save(force_insert=True) 34 | 35 | # Won't work because we can't insert a pk of the same value. 36 | c.value = 5 37 | with self.assertRaises(IntegrityError): 38 | with transaction.atomic(): 39 | c.save(force_insert=True) 40 | 41 | # Trying to update should still fail, even with manual primary keys, if 42 | # the data isn't in the database already. 43 | obj = WithCustomPK(name=1, value=1) 44 | with self.assertRaises(DatabaseError): 45 | with transaction.atomic(): 46 | obj.save(force_update=True) 47 | 48 | 49 | class InheritanceTests(TestCase): 50 | def test_force_update_on_inherited_model(self): 51 | a = InheritedCounter(name="count", value=1, tag="spam") 52 | a.save() 53 | a.save(force_update=True) 54 | 55 | def test_force_update_on_proxy_model(self): 56 | a = ProxyCounter(name="count", value=1) 57 | a.save() 58 | a.save(force_update=True) 59 | 60 | def test_force_update_on_inherited_model_without_fields(self): 61 | ''' 62 | Issue 13864: force_update fails on subclassed models, if they don't 63 | specify custom fields. 64 | ''' 65 | a = SubCounter(name="count", value=1) 66 | a.save() 67 | a.value = 2 68 | a.save(force_update=True) 69 | -------------------------------------------------------------------------------- /tests/django20/inspectdb/models.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | 6 | 7 | class People(models.Model): 8 | name = models.CharField(max_length=255) 9 | parent = models.ForeignKey('self') 10 | 11 | class Message(models.Model): 12 | from_field = models.ForeignKey(People, db_column='from_id') 13 | 14 | class PeopleData(models.Model): 15 | people_pk = models.ForeignKey(People, primary_key=True) 16 | ssn = models.CharField(max_length=11) 17 | 18 | class PeopleMoreData(models.Model): 19 | people_unique = models.ForeignKey(People, unique=True) 20 | license = models.CharField(max_length=255) 21 | 22 | class DigitsInColumnName(models.Model): 23 | all_digits = models.CharField(max_length=11, db_column='123') 24 | leading_digit = models.CharField(max_length=11, db_column='4extra') 25 | leading_digits = models.CharField(max_length=11, db_column='45extra') 26 | 27 | class SpecialColumnName(models.Model): 28 | field = models.IntegerField(db_column='field') 29 | # Underscores 30 | field_field_0 = models.IntegerField(db_column='Field_') 31 | field_field_1 = models.IntegerField(db_column='Field__') 32 | field_field_2 = models.IntegerField(db_column='__field') 33 | # Other chars 34 | prc_x = models.IntegerField(db_column='prc(%) x') 35 | non_ascii = models.IntegerField(db_column='tamaño') 36 | 37 | class ColumnTypes(models.Model): 38 | id = models.AutoField(primary_key=True) 39 | big_int_field = models.BigIntegerField() 40 | bool_field = models.BooleanField(default=False) 41 | null_bool_field = models.NullBooleanField() 42 | char_field = models.CharField(max_length=10) 43 | comma_separated_int_field = models.CommaSeparatedIntegerField(max_length=99) 44 | date_field = models.DateField() 45 | date_time_field = models.DateTimeField() 46 | decimal_field = models.DecimalField(max_digits=6, decimal_places=1) 47 | email_field = models.EmailField() 48 | file_field = models.FileField(upload_to="unused") 49 | file_path_field = models.FilePathField() 50 | float_field = models.FloatField() 51 | int_field = models.IntegerField() 52 | ip_address_field = models.IPAddressField() 53 | gen_ip_adress_field = models.GenericIPAddressField(protocol="ipv4") 54 | pos_int_field = models.PositiveIntegerField() 55 | pos_small_int_field = models.PositiveSmallIntegerField() 56 | slug_field = models.SlugField() 57 | small_int_field = models.SmallIntegerField() 58 | text_field = models.TextField() 59 | time_field = models.TimeField() 60 | url_field = models.URLField() 61 | -------------------------------------------------------------------------------- /tests/django20/db_typecasts/tests.py: -------------------------------------------------------------------------------- 1 | # Unit tests for typecast functions in django.db.backends.util 2 | 3 | import datetime 4 | 5 | from django.db.backends import util as typecasts 6 | from django.utils import six 7 | from django.utils import unittest 8 | 9 | 10 | TEST_CASES = { 11 | 'typecast_date': ( 12 | ('', None), 13 | (None, None), 14 | ('2005-08-11', datetime.date(2005, 8, 11)), 15 | ('1990-01-01', datetime.date(1990, 1, 1)), 16 | ), 17 | 'typecast_time': ( 18 | ('', None), 19 | (None, None), 20 | ('0:00:00', datetime.time(0, 0)), 21 | ('0:30:00', datetime.time(0, 30)), 22 | ('8:50:00', datetime.time(8, 50)), 23 | ('08:50:00', datetime.time(8, 50)), 24 | ('12:00:00', datetime.time(12, 00)), 25 | ('12:30:00', datetime.time(12, 30)), 26 | ('13:00:00', datetime.time(13, 00)), 27 | ('23:59:00', datetime.time(23, 59)), 28 | ('00:00:12', datetime.time(0, 0, 12)), 29 | ('00:00:12.5', datetime.time(0, 0, 12, 500000)), 30 | ('7:22:13.312', datetime.time(7, 22, 13, 312000)), 31 | ), 32 | 'typecast_timestamp': ( 33 | ('', None), 34 | (None, None), 35 | ('2005-08-11 0:00:00', datetime.datetime(2005, 8, 11)), 36 | ('2005-08-11 0:30:00', datetime.datetime(2005, 8, 11, 0, 30)), 37 | ('2005-08-11 8:50:30', datetime.datetime(2005, 8, 11, 8, 50, 30)), 38 | ('2005-08-11 8:50:30.123', datetime.datetime(2005, 8, 11, 8, 50, 30, 123000)), 39 | ('2005-08-11 8:50:30.9', datetime.datetime(2005, 8, 11, 8, 50, 30, 900000)), 40 | ('2005-08-11 8:50:30.312-05', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), 41 | ('2005-08-11 8:50:30.312+02', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)), 42 | # ticket 14453 43 | ('2010-10-12 15:29:22.063202', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), 44 | ('2010-10-12 15:29:22.063202-03', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), 45 | ('2010-10-12 15:29:22.063202+04', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), 46 | ('2010-10-12 15:29:22.0632021', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), 47 | ('2010-10-12 15:29:22.0632029', datetime.datetime(2010, 10, 12, 15, 29, 22, 63202)), 48 | ), 49 | } 50 | 51 | class DBTypeCasts(unittest.TestCase): 52 | def test_typeCasts(self): 53 | for k, v in six.iteritems(TEST_CASES): 54 | for inpt, expected in v: 55 | got = getattr(typecasts, k)(inpt) 56 | self.assertEqual(got, expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got)) 57 | -------------------------------------------------------------------------------- /tests/django20/commands_sql/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.core.management.color import no_style 4 | from django.core.management.sql import (sql_create, sql_delete, sql_indexes, 5 | sql_destroy_indexes, sql_all) 6 | from django.db import connections, DEFAULT_DB_ALIAS, models 7 | from django.test import TestCase 8 | from django.utils import six 9 | 10 | # See also initial_sql_regress for 'custom_sql_for_model' tests 11 | 12 | 13 | class SQLCommandsTestCase(TestCase): 14 | """Tests for several functions in django/core/management/sql.py""" 15 | def count_ddl(self, output, cmd): 16 | return len([o for o in output if o.startswith(cmd)]) 17 | 18 | def test_sql_create(self): 19 | app = models.get_app('commands_sql') 20 | output = sql_create(app, no_style(), connections[DEFAULT_DB_ALIAS]) 21 | create_tables = [o for o in output if o.startswith('CREATE TABLE')] 22 | self.assertEqual(len(create_tables), 3) 23 | # Lower so that Oracle's upper case tbl names wont break 24 | sql = create_tables[-1].lower() 25 | six.assertRegex(self, sql, r'^create table .commands_sql_book.*') 26 | 27 | def test_sql_delete(self): 28 | app = models.get_app('commands_sql') 29 | output = sql_delete(app, no_style(), connections[DEFAULT_DB_ALIAS]) 30 | drop_tables = [o for o in output if o.startswith('DROP TABLE')] 31 | self.assertEqual(len(drop_tables), 3) 32 | # Lower so that Oracle's upper case tbl names wont break 33 | sql = drop_tables[-1].lower() 34 | six.assertRegex(self, sql, r'^drop table .commands_sql_comment.*') 35 | 36 | def test_sql_indexes(self): 37 | app = models.get_app('commands_sql') 38 | output = sql_indexes(app, no_style(), connections[DEFAULT_DB_ALIAS]) 39 | # PostgreSQL creates one additional index for CharField 40 | self.assertIn(self.count_ddl(output, 'CREATE INDEX'), [3, 4]) 41 | 42 | def test_sql_destroy_indexes(self): 43 | app = models.get_app('commands_sql') 44 | output = sql_destroy_indexes(app, no_style(), connections[DEFAULT_DB_ALIAS]) 45 | # PostgreSQL creates one additional index for CharField 46 | self.assertIn(self.count_ddl(output, 'DROP INDEX'), [3, 4]) 47 | 48 | def test_sql_all(self): 49 | app = models.get_app('commands_sql') 50 | output = sql_all(app, no_style(), connections[DEFAULT_DB_ALIAS]) 51 | 52 | self.assertEqual(self.count_ddl(output, 'CREATE TABLE'), 3) 53 | # PostgreSQL creates one additional index for CharField 54 | self.assertIn(self.count_ddl(output, 'CREATE INDEX'), [3, 4]) 55 | -------------------------------------------------------------------------------- /tests/django20/custom_managers/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | from django.utils import six 5 | 6 | from .models import Person, Book, Car, PersonManager, PublishedBookManager 7 | 8 | 9 | class CustomManagerTests(TestCase): 10 | def test_manager(self): 11 | p1 = Person.objects.create(first_name="Bugs", last_name="Bunny", fun=True) 12 | p2 = Person.objects.create(first_name="Droopy", last_name="Dog", fun=False) 13 | 14 | self.assertQuerysetEqual( 15 | Person.objects.get_fun_people(), [ 16 | "Bugs Bunny" 17 | ], 18 | six.text_type 19 | ) 20 | # The RelatedManager used on the 'books' descriptor extends the default 21 | # manager 22 | self.assertIsInstance(p2.books, PublishedBookManager) 23 | 24 | b1 = Book.published_objects.create( 25 | title="How to program", author="Rodney Dangerfield", is_published=True 26 | ) 27 | b2 = Book.published_objects.create( 28 | title="How to be smart", author="Albert Einstein", is_published=False 29 | ) 30 | 31 | # The default manager, "objects", doesn't exist, because a custom one 32 | # was provided. 33 | self.assertRaises(AttributeError, lambda: Book.objects) 34 | 35 | # The RelatedManager used on the 'authors' descriptor extends the 36 | # default manager 37 | self.assertIsInstance(b2.authors, PersonManager) 38 | 39 | self.assertQuerysetEqual( 40 | Book.published_objects.all(), [ 41 | "How to program", 42 | ], 43 | lambda b: b.title 44 | ) 45 | 46 | c1 = Car.cars.create(name="Corvette", mileage=21, top_speed=180) 47 | c2 = Car.cars.create(name="Neon", mileage=31, top_speed=100) 48 | 49 | self.assertQuerysetEqual( 50 | Car.cars.order_by("name"), [ 51 | "Corvette", 52 | "Neon", 53 | ], 54 | lambda c: c.name 55 | ) 56 | 57 | self.assertQuerysetEqual( 58 | Car.fast_cars.all(), [ 59 | "Corvette", 60 | ], 61 | lambda c: c.name 62 | ) 63 | 64 | # Each model class gets a "_default_manager" attribute, which is a 65 | # reference to the first manager defined in the class. In this case, 66 | # it's "cars". 67 | 68 | self.assertQuerysetEqual( 69 | Car._default_manager.order_by("name"), [ 70 | "Corvette", 71 | "Neon", 72 | ], 73 | lambda c: c.name 74 | ) 75 | -------------------------------------------------------------------------------- /tests/django20/model_regress/models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from django.db import models 3 | from django.utils.encoding import python_2_unicode_compatible 4 | 5 | 6 | CHOICES = ( 7 | (1, 'first'), 8 | (2, 'second'), 9 | ) 10 | 11 | 12 | @python_2_unicode_compatible 13 | class Article(models.Model): 14 | headline = models.CharField(max_length=100, default='Default headline') 15 | pub_date = models.DateTimeField() 16 | status = models.IntegerField(blank=True, null=True, choices=CHOICES) 17 | misc_data = models.CharField(max_length=100, blank=True) 18 | article_text = models.TextField() 19 | 20 | class Meta: 21 | ordering = ('pub_date', 'headline') 22 | # A utf-8 verbose name (Ångström's Articles) to test they are valid. 23 | verbose_name = "\xc3\x85ngstr\xc3\xb6m's Articles" 24 | 25 | def __str__(self): 26 | return self.headline 27 | 28 | 29 | class Movie(models.Model): 30 | #5218: Test models with non-default primary keys / AutoFields 31 | movie_id = models.AutoField(primary_key=True) 32 | name = models.CharField(max_length=60) 33 | 34 | 35 | class Party(models.Model): 36 | when = models.DateField(null=True) 37 | 38 | 39 | class Event(models.Model): 40 | when = models.DateTimeField() 41 | 42 | 43 | @python_2_unicode_compatible 44 | class Department(models.Model): 45 | id = models.PositiveIntegerField(primary_key=True) 46 | name = models.CharField(max_length=200) 47 | 48 | def __str__(self): 49 | return self.name 50 | 51 | 52 | @python_2_unicode_compatible 53 | class Worker(models.Model): 54 | department = models.ForeignKey(Department) 55 | name = models.CharField(max_length=200) 56 | 57 | def __str__(self): 58 | return self.name 59 | 60 | 61 | @python_2_unicode_compatible 62 | class BrokenUnicodeMethod(models.Model): 63 | name = models.CharField(max_length=7) 64 | 65 | def __str__(self): 66 | # Intentionally broken (invalid start byte in byte string). 67 | return b'Name\xff: %s'.decode() % self.name 68 | 69 | 70 | class NonAutoPK(models.Model): 71 | name = models.CharField(max_length=10, primary_key=True) 72 | 73 | 74 | #18432: Chained foreign keys with to_field produce incorrect query 75 | class Model1(models.Model): 76 | pkey = models.IntegerField(unique=True, db_index=True) 77 | 78 | 79 | class Model2(models.Model): 80 | model1 = models.ForeignKey(Model1, unique=True, to_field='pkey') 81 | 82 | 83 | class Model3(models.Model): 84 | model2 = models.ForeignKey(Model2, unique=True, to_field='model1') 85 | 86 | 87 | class Slicer(models.Model): 88 | field1 = models.IntegerField() 89 | field2 = models.IntegerField() 90 | -------------------------------------------------------------------------------- /tests/django20/defer_regress/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | Regression tests for defer() / only() behavior. 3 | """ 4 | 5 | from django.db import models 6 | from django.utils.encoding import python_2_unicode_compatible 7 | 8 | 9 | @python_2_unicode_compatible 10 | class Item(models.Model): 11 | name = models.CharField(max_length=15) 12 | text = models.TextField(default="xyzzy") 13 | value = models.IntegerField() 14 | other_value = models.IntegerField(default=0) 15 | 16 | def __str__(self): 17 | return self.name 18 | 19 | class RelatedItem(models.Model): 20 | item = models.ForeignKey(Item) 21 | 22 | class Child(models.Model): 23 | name = models.CharField(max_length=10) 24 | value = models.IntegerField() 25 | 26 | @python_2_unicode_compatible 27 | class Leaf(models.Model): 28 | name = models.CharField(max_length=10) 29 | child = models.ForeignKey(Child) 30 | second_child = models.ForeignKey(Child, related_name="other", null=True) 31 | value = models.IntegerField(default=42) 32 | 33 | def __str__(self): 34 | return self.name 35 | 36 | class ResolveThis(models.Model): 37 | num = models.FloatField() 38 | name = models.CharField(max_length=16) 39 | 40 | class Proxy(Item): 41 | class Meta: 42 | proxy = True 43 | 44 | @python_2_unicode_compatible 45 | class SimpleItem(models.Model): 46 | name = models.CharField(max_length=15) 47 | value = models.IntegerField() 48 | 49 | def __str__(self): 50 | return self.name 51 | 52 | class Feature(models.Model): 53 | item = models.ForeignKey(SimpleItem) 54 | 55 | class SpecialFeature(models.Model): 56 | feature = models.ForeignKey(Feature) 57 | 58 | class OneToOneItem(models.Model): 59 | item = models.OneToOneField(Item, related_name="one_to_one_item") 60 | name = models.CharField(max_length=15) 61 | 62 | class ItemAndSimpleItem(models.Model): 63 | item = models.ForeignKey(Item) 64 | simple = models.ForeignKey(SimpleItem) 65 | 66 | class Profile(models.Model): 67 | profile1 = models.CharField(max_length=1000, default='profile1') 68 | 69 | class Location(models.Model): 70 | location1 = models.CharField(max_length=1000, default='location1') 71 | 72 | class Item(models.Model): 73 | pass 74 | 75 | class Request(models.Model): 76 | profile = models.ForeignKey(Profile, null=True, blank=True) 77 | location = models.ForeignKey(Location) 78 | items = models.ManyToManyField(Item) 79 | 80 | request1 = models.CharField(default='request1', max_length=1000) 81 | request2 = models.CharField(default='request2', max_length=1000) 82 | request3 = models.CharField(default='request3', max_length=1000) 83 | request4 = models.CharField(default='request4', max_length=1000) 84 | -------------------------------------------------------------------------------- /tests/django20/m2m_through/models.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | # M2M described on one of the models 8 | @python_2_unicode_compatible 9 | class Person(models.Model): 10 | name = models.CharField(max_length=128) 11 | 12 | class Meta: 13 | ordering = ('name',) 14 | 15 | def __str__(self): 16 | return self.name 17 | 18 | @python_2_unicode_compatible 19 | class Group(models.Model): 20 | name = models.CharField(max_length=128) 21 | members = models.ManyToManyField(Person, through='Membership') 22 | custom_members = models.ManyToManyField(Person, through='CustomMembership', related_name="custom") 23 | nodefaultsnonulls = models.ManyToManyField(Person, through='TestNoDefaultsOrNulls', related_name="testnodefaultsnonulls") 24 | 25 | class Meta: 26 | ordering = ('name',) 27 | 28 | def __str__(self): 29 | return self.name 30 | 31 | @python_2_unicode_compatible 32 | class Membership(models.Model): 33 | person = models.ForeignKey(Person) 34 | group = models.ForeignKey(Group) 35 | date_joined = models.DateTimeField(default=datetime.now) 36 | invite_reason = models.CharField(max_length=64, null=True) 37 | 38 | class Meta: 39 | ordering = ('date_joined', 'invite_reason', 'group') 40 | 41 | def __str__(self): 42 | return "%s is a member of %s" % (self.person.name, self.group.name) 43 | 44 | @python_2_unicode_compatible 45 | class CustomMembership(models.Model): 46 | person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name") 47 | group = models.ForeignKey(Group) 48 | weird_fk = models.ForeignKey(Membership, null=True) 49 | date_joined = models.DateTimeField(default=datetime.now) 50 | 51 | def __str__(self): 52 | return "%s is a member of %s" % (self.person.name, self.group.name) 53 | 54 | class Meta: 55 | db_table = "test_table" 56 | 57 | class TestNoDefaultsOrNulls(models.Model): 58 | person = models.ForeignKey(Person) 59 | group = models.ForeignKey(Group) 60 | nodefaultnonull = models.CharField(max_length=5) 61 | 62 | @python_2_unicode_compatible 63 | class PersonSelfRefM2M(models.Model): 64 | name = models.CharField(max_length=5) 65 | friends = models.ManyToManyField('self', through="Friendship", symmetrical=False) 66 | 67 | def __str__(self): 68 | return self.name 69 | 70 | class Friendship(models.Model): 71 | first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set") 72 | second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set") 73 | date_friended = models.DateTimeField() 74 | -------------------------------------------------------------------------------- /tests/django20/m2m_multiple/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from datetime import datetime 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Article, Category 8 | 9 | 10 | class M2MMultipleTests(TestCase): 11 | def test_multiple(self): 12 | c1, c2, c3, c4 = [ 13 | Category.objects.create(name=name) 14 | for name in ["Sports", "News", "Crime", "Life"] 15 | ] 16 | 17 | a1 = Article.objects.create( 18 | headline="Area man steals", pub_date=datetime(2005, 11, 27) 19 | ) 20 | a1.primary_categories.add(c2, c3) 21 | a1.secondary_categories.add(c4) 22 | 23 | a2 = Article.objects.create( 24 | headline="Area man runs", pub_date=datetime(2005, 11, 28) 25 | ) 26 | a2.primary_categories.add(c1, c2) 27 | a2.secondary_categories.add(c4) 28 | 29 | self.assertQuerysetEqual( 30 | a1.primary_categories.all(), [ 31 | "Crime", 32 | "News", 33 | ], 34 | lambda c: c.name 35 | ) 36 | self.assertQuerysetEqual( 37 | a2.primary_categories.all(), [ 38 | "News", 39 | "Sports", 40 | ], 41 | lambda c: c.name 42 | ) 43 | self.assertQuerysetEqual( 44 | a1.secondary_categories.all(), [ 45 | "Life", 46 | ], 47 | lambda c: c.name 48 | ) 49 | self.assertQuerysetEqual( 50 | c1.primary_article_set.all(), [ 51 | "Area man runs", 52 | ], 53 | lambda a: a.headline 54 | ) 55 | self.assertQuerysetEqual( 56 | c1.secondary_article_set.all(), [] 57 | ) 58 | self.assertQuerysetEqual( 59 | c2.primary_article_set.all(), [ 60 | "Area man steals", 61 | "Area man runs", 62 | ], 63 | lambda a: a.headline 64 | ) 65 | self.assertQuerysetEqual( 66 | c2.secondary_article_set.all(), [] 67 | ) 68 | self.assertQuerysetEqual( 69 | c3.primary_article_set.all(), [ 70 | "Area man steals", 71 | ], 72 | lambda a: a.headline 73 | ) 74 | self.assertQuerysetEqual( 75 | c3.secondary_article_set.all(), [] 76 | ) 77 | self.assertQuerysetEqual( 78 | c4.primary_article_set.all(), [] 79 | ) 80 | self.assertQuerysetEqual( 81 | c4.secondary_article_set.all(), [ 82 | "Area man steals", 83 | "Area man runs", 84 | ], 85 | lambda a: a.headline 86 | ) 87 | -------------------------------------------------------------------------------- /tests/django20/multiple_database/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.contrib.auth.models import User 4 | from django.contrib.contenttypes.models import ContentType 5 | from django.contrib.contenttypes import generic 6 | from django.db import models 7 | from django.utils.encoding import python_2_unicode_compatible 8 | 9 | 10 | @python_2_unicode_compatible 11 | class Review(models.Model): 12 | source = models.CharField(max_length=100) 13 | content_type = models.ForeignKey(ContentType) 14 | object_id = models.PositiveIntegerField() 15 | content_object = generic.GenericForeignKey() 16 | 17 | def __str__(self): 18 | return self.source 19 | 20 | class Meta: 21 | ordering = ('source',) 22 | 23 | class PersonManager(models.Manager): 24 | def get_by_natural_key(self, name): 25 | return self.get(name=name) 26 | 27 | @python_2_unicode_compatible 28 | class Person(models.Model): 29 | objects = PersonManager() 30 | name = models.CharField(max_length=100) 31 | 32 | def __str__(self): 33 | return self.name 34 | 35 | class Meta: 36 | ordering = ('name',) 37 | 38 | # This book manager doesn't do anything interesting; it just 39 | # exists to strip out the 'extra_arg' argument to certain 40 | # calls. This argument is used to establish that the BookManager 41 | # is actually getting used when it should be. 42 | class BookManager(models.Manager): 43 | def create(self, *args, **kwargs): 44 | kwargs.pop('extra_arg', None) 45 | return super(BookManager, self).create(*args, **kwargs) 46 | 47 | def get_or_create(self, *args, **kwargs): 48 | kwargs.pop('extra_arg', None) 49 | return super(BookManager, self).get_or_create(*args, **kwargs) 50 | 51 | @python_2_unicode_compatible 52 | class Book(models.Model): 53 | objects = BookManager() 54 | title = models.CharField(max_length=100) 55 | published = models.DateField() 56 | authors = models.ManyToManyField(Person) 57 | editor = models.ForeignKey(Person, null=True, related_name='edited') 58 | reviews = generic.GenericRelation(Review) 59 | pages = models.IntegerField(default=100) 60 | 61 | def __str__(self): 62 | return self.title 63 | 64 | class Meta: 65 | ordering = ('title',) 66 | 67 | @python_2_unicode_compatible 68 | class Pet(models.Model): 69 | name = models.CharField(max_length=100) 70 | owner = models.ForeignKey(Person) 71 | 72 | def __str__(self): 73 | return self.name 74 | 75 | class Meta: 76 | ordering = ('name',) 77 | 78 | class UserProfile(models.Model): 79 | user = models.OneToOneField(User, null=True) 80 | flavor = models.CharField(max_length=100) 81 | 82 | class Meta: 83 | ordering = ('flavor',) 84 | -------------------------------------------------------------------------------- /tests/django20/m2m_regress/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import models as auth 2 | from django.db import models 3 | from django.utils.encoding import python_2_unicode_compatible 4 | 5 | # No related name is needed here, since symmetrical relations are not 6 | # explicitly reversible. 7 | @python_2_unicode_compatible 8 | class SelfRefer(models.Model): 9 | name = models.CharField(max_length=10) 10 | references = models.ManyToManyField('self') 11 | related = models.ManyToManyField('self') 12 | 13 | def __str__(self): 14 | return self.name 15 | 16 | @python_2_unicode_compatible 17 | class Tag(models.Model): 18 | name = models.CharField(max_length=10) 19 | 20 | def __str__(self): 21 | return self.name 22 | 23 | # Regression for #11956 -- a many to many to the base class 24 | @python_2_unicode_compatible 25 | class TagCollection(Tag): 26 | tags = models.ManyToManyField(Tag, related_name='tag_collections') 27 | 28 | def __str__(self): 29 | return self.name 30 | 31 | # A related_name is required on one of the ManyToManyField entries here because 32 | # they are both addressable as reverse relations from Tag. 33 | @python_2_unicode_compatible 34 | class Entry(models.Model): 35 | name = models.CharField(max_length=10) 36 | topics = models.ManyToManyField(Tag) 37 | related = models.ManyToManyField(Tag, related_name="similar") 38 | 39 | def __str__(self): 40 | return self.name 41 | 42 | # Two models both inheriting from a base model with a self-referential m2m field 43 | class SelfReferChild(SelfRefer): 44 | pass 45 | 46 | class SelfReferChildSibling(SelfRefer): 47 | pass 48 | 49 | # Many-to-Many relation between models, where one of the PK's isn't an Autofield 50 | class Line(models.Model): 51 | name = models.CharField(max_length=100) 52 | 53 | class Worksheet(models.Model): 54 | id = models.CharField(primary_key=True, max_length=100) 55 | lines = models.ManyToManyField(Line, blank=True, null=True) 56 | 57 | # Regression for #11226 -- A model with the same name that another one to 58 | # which it has a m2m relation. This shouldn't cause a name clash between 59 | # the automatically created m2m intermediary table FK field names when 60 | # running syncdb 61 | class User(models.Model): 62 | name = models.CharField(max_length=30) 63 | friends = models.ManyToManyField(auth.User) 64 | 65 | 66 | class BadModelWithSplit(models.Model): 67 | name = models.CharField(max_length=1) 68 | 69 | def split(self): 70 | raise RuntimeError('split should not be called') 71 | 72 | class Meta: 73 | abstract = True 74 | 75 | 76 | class RegressionModelSplit(BadModelWithSplit): 77 | """ 78 | Model with a split method should not cause an error in add_lazy_relation 79 | """ 80 | others = models.ManyToManyField('self') 81 | -------------------------------------------------------------------------------- /tests/test_sqlite.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008, django-pyodbc developers (see README.rst). 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of django-sql-server nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # This is an example test settings file for use with the Django test suite. 30 | # 31 | # The 'sqlite3' backend requires only the ENGINE setting (an in- 32 | # memory database will be used). All other backends will require a 33 | # NAME and potentially authentication information. See the 34 | # following section in the docs for more information: 35 | # 36 | # https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/ 37 | # 38 | # The different databases that Django supports behave differently in certain 39 | # situations, so it is recommended to run the test suite against as many 40 | # database backends as possible. You may want to create a separate settings 41 | # file for each of the backends you test against. 42 | 43 | DATABASES = { 44 | 'default': { 45 | 'ENGINE': 'django.db.backends.sqlite3' 46 | }, 47 | 'other': { 48 | 'ENGINE': 'django.db.backends.sqlite3', 49 | } 50 | } 51 | 52 | SECRET_KEY = "django_tests_secret_key" 53 | 54 | # Use a fast hasher to speed up tests. 55 | PASSWORD_HASHERS = ( 56 | 'django.contrib.auth.hashers.MD5PasswordHasher', 57 | ) 58 | 59 | TEMPLATE_DIRS = [ '.' ] -------------------------------------------------------------------------------- /tests/django20/dates/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import datetime 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Article, Comment, Category 8 | 9 | 10 | class DatesTests(TestCase): 11 | def test_related_model_traverse(self): 12 | a1 = Article.objects.create( 13 | title="First one", 14 | pub_date=datetime.date(2005, 7, 28), 15 | ) 16 | a2 = Article.objects.create( 17 | title="Another one", 18 | pub_date=datetime.date(2010, 7, 28), 19 | ) 20 | a3 = Article.objects.create( 21 | title="Third one, in the first day", 22 | pub_date=datetime.date(2005, 7, 28), 23 | ) 24 | 25 | a1.comments.create( 26 | text="Im the HULK!", 27 | pub_date=datetime.date(2005, 7, 28), 28 | ) 29 | a1.comments.create( 30 | text="HULK SMASH!", 31 | pub_date=datetime.date(2005, 7, 29), 32 | ) 33 | a2.comments.create( 34 | text="LMAO", 35 | pub_date=datetime.date(2010, 7, 28), 36 | ) 37 | a3.comments.create( 38 | text="+1", 39 | pub_date=datetime.date(2005, 8, 29), 40 | ) 41 | 42 | c = Category.objects.create(name="serious-news") 43 | c.articles.add(a1, a3) 44 | 45 | self.assertQuerysetEqual( 46 | Comment.objects.dates("article__pub_date", "year"), [ 47 | datetime.date(2005, 1, 1), 48 | datetime.date(2010, 1, 1), 49 | ], 50 | lambda d: d, 51 | ) 52 | self.assertQuerysetEqual( 53 | Comment.objects.dates("article__pub_date", "month"), [ 54 | datetime.date(2005, 7, 1), 55 | datetime.date(2010, 7, 1), 56 | ], 57 | lambda d: d 58 | ) 59 | self.assertQuerysetEqual( 60 | Comment.objects.dates("article__pub_date", "day"), [ 61 | datetime.date(2005, 7, 28), 62 | datetime.date(2010, 7, 28), 63 | ], 64 | lambda d: d 65 | ) 66 | self.assertQuerysetEqual( 67 | Article.objects.dates("comments__pub_date", "day"), [ 68 | datetime.date(2005, 7, 28), 69 | datetime.date(2005, 7, 29), 70 | datetime.date(2005, 8, 29), 71 | datetime.date(2010, 7, 28), 72 | ], 73 | lambda d: d 74 | ) 75 | self.assertQuerysetEqual( 76 | Article.objects.dates("comments__approval_date", "day"), [] 77 | ) 78 | self.assertQuerysetEqual( 79 | Category.objects.dates("articles__pub_date", "day"), [ 80 | datetime.date(2005, 7, 28), 81 | ], 82 | lambda d: d, 83 | ) 84 | -------------------------------------------------------------------------------- /tests/django20/get_or_create_regress/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | 5 | from .models import Author, Publisher 6 | 7 | 8 | class GetOrCreateTests(TestCase): 9 | def test_related(self): 10 | p = Publisher.objects.create(name="Acme Publishing") 11 | # Create a book through the publisher. 12 | book, created = p.books.get_or_create(name="The Book of Ed & Fred") 13 | self.assertTrue(created) 14 | # The publisher should have one book. 15 | self.assertEqual(p.books.count(), 1) 16 | 17 | # Try get_or_create again, this time nothing should be created. 18 | book, created = p.books.get_or_create(name="The Book of Ed & Fred") 19 | self.assertFalse(created) 20 | # And the publisher should still have one book. 21 | self.assertEqual(p.books.count(), 1) 22 | 23 | # Add an author to the book. 24 | ed, created = book.authors.get_or_create(name="Ed") 25 | self.assertTrue(created) 26 | # The book should have one author. 27 | self.assertEqual(book.authors.count(), 1) 28 | 29 | # Try get_or_create again, this time nothing should be created. 30 | ed, created = book.authors.get_or_create(name="Ed") 31 | self.assertFalse(created) 32 | # And the book should still have one author. 33 | self.assertEqual(book.authors.count(), 1) 34 | 35 | # Add a second author to the book. 36 | fred, created = book.authors.get_or_create(name="Fred") 37 | self.assertTrue(created) 38 | 39 | # The book should have two authors now. 40 | self.assertEqual(book.authors.count(), 2) 41 | 42 | # Create an Author not tied to any books. 43 | Author.objects.create(name="Ted") 44 | 45 | # There should be three Authors in total. The book object should have two. 46 | self.assertEqual(Author.objects.count(), 3) 47 | self.assertEqual(book.authors.count(), 2) 48 | 49 | # Try creating a book through an author. 50 | _, created = ed.books.get_or_create(name="Ed's Recipes", publisher=p) 51 | self.assertTrue(created) 52 | 53 | # Now Ed has two Books, Fred just one. 54 | self.assertEqual(ed.books.count(), 2) 55 | self.assertEqual(fred.books.count(), 1) 56 | 57 | # Use the publisher's primary key value instead of a model instance. 58 | _, created = ed.books.get_or_create(name='The Great Book of Ed', publisher_id=p.id) 59 | self.assertTrue(created) 60 | 61 | # Try get_or_create again, this time nothing should be created. 62 | _, created = ed.books.get_or_create(name='The Great Book of Ed', publisher_id=p.id) 63 | self.assertFalse(created) 64 | 65 | # The publisher should have three books. 66 | self.assertEqual(p.books.count(), 3) 67 | -------------------------------------------------------------------------------- /tests/django20/m2m_and_m2o/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.db.models import Q 4 | from django.test import TestCase 5 | 6 | from .models import Issue, User, UnicodeReferenceModel 7 | 8 | 9 | class RelatedObjectTests(TestCase): 10 | def test_m2m_and_m2o(self): 11 | r = User.objects.create(username="russell") 12 | g = User.objects.create(username="gustav") 13 | 14 | i1 = Issue(num=1) 15 | i1.client = r 16 | i1.save() 17 | 18 | i2 = Issue(num=2) 19 | i2.client = r 20 | i2.save() 21 | i2.cc.add(r) 22 | 23 | i3 = Issue(num=3) 24 | i3.client = g 25 | i3.save() 26 | i3.cc.add(r) 27 | 28 | self.assertQuerysetEqual( 29 | Issue.objects.filter(client=r.id), [ 30 | 1, 31 | 2, 32 | ], 33 | lambda i: i.num 34 | ) 35 | self.assertQuerysetEqual( 36 | Issue.objects.filter(client=g.id), [ 37 | 3, 38 | ], 39 | lambda i: i.num 40 | ) 41 | self.assertQuerysetEqual( 42 | Issue.objects.filter(cc__id__exact=g.id), [] 43 | ) 44 | self.assertQuerysetEqual( 45 | Issue.objects.filter(cc__id__exact=r.id), [ 46 | 2, 47 | 3, 48 | ], 49 | lambda i: i.num 50 | ) 51 | 52 | # These queries combine results from the m2m and the m2o relationships. 53 | # They're three ways of saying the same thing. 54 | self.assertQuerysetEqual( 55 | Issue.objects.filter(Q(cc__id__exact = r.id) | Q(client=r.id)), [ 56 | 1, 57 | 2, 58 | 3, 59 | ], 60 | lambda i: i.num 61 | ) 62 | self.assertQuerysetEqual( 63 | Issue.objects.filter(cc__id__exact=r.id) | Issue.objects.filter(client=r.id), [ 64 | 1, 65 | 2, 66 | 3, 67 | ], 68 | lambda i: i.num 69 | ) 70 | self.assertQuerysetEqual( 71 | Issue.objects.filter(Q(client=r.id) | Q(cc__id__exact=r.id)), [ 72 | 1, 73 | 2, 74 | 3, 75 | ], 76 | lambda i: i.num 77 | ) 78 | 79 | class RelatedObjectTests(TestCase): 80 | def test_m2m_with_unicode_reference(self): 81 | """ 82 | Regression test for #6045: references to other models can be unicode 83 | strings, providing they are directly convertible to ASCII. 84 | """ 85 | m1=UnicodeReferenceModel.objects.create() 86 | m2=UnicodeReferenceModel.objects.create() 87 | m2.others.add(m1) # used to cause an error (see ticket #6045) 88 | m2.save() 89 | list(m2.others.all()) # Force retrieval. 90 | 91 | -------------------------------------------------------------------------------- /tests/django20/string_lookup/tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import absolute_import, unicode_literals 3 | 4 | from django.test import TestCase 5 | from .models import Foo, Whiz, Bar, Article, Base, Child 6 | 7 | 8 | class StringLookupTests(TestCase): 9 | 10 | def test_string_form_referencing(self): 11 | """ 12 | Regression test for #1661 and #1662 13 | 14 | Check that string form referencing of 15 | models works, both as pre and post reference, on all RelatedField types. 16 | """ 17 | 18 | f1 = Foo(name="Foo1") 19 | f1.save() 20 | f2 = Foo(name="Foo2") 21 | f2.save() 22 | 23 | w1 = Whiz(name="Whiz1") 24 | w1.save() 25 | 26 | b1 = Bar(name="Bar1", normal=f1, fwd=w1, back=f2) 27 | b1.save() 28 | 29 | self.assertEqual(b1.normal, f1) 30 | 31 | self.assertEqual(b1.fwd, w1) 32 | 33 | self.assertEqual(b1.back, f2) 34 | 35 | base1 = Base(name="Base1") 36 | base1.save() 37 | 38 | child1 = Child(name="Child1", parent=base1) 39 | child1.save() 40 | 41 | self.assertEqual(child1.parent, base1) 42 | 43 | def test_unicode_chars_in_queries(self): 44 | """ 45 | Regression tests for #3937 46 | 47 | make sure we can use unicode characters in queries. 48 | If these tests fail on MySQL, it's a problem with the test setup. 49 | A properly configured UTF-8 database can handle this. 50 | """ 51 | 52 | fx = Foo(name='Bjorn', friend='François') 53 | fx.save() 54 | self.assertEqual(Foo.objects.get(friend__contains='\xe7'), fx) 55 | 56 | # We can also do the above query using UTF-8 strings. 57 | self.assertEqual(Foo.objects.get(friend__contains=b'\xc3\xa7'), fx) 58 | 59 | def test_queries_on_textfields(self): 60 | """ 61 | Regression tests for #5087 62 | 63 | make sure we can perform queries on TextFields. 64 | """ 65 | 66 | a = Article(name='Test', text='The quick brown fox jumps over the lazy dog.') 67 | a.save() 68 | self.assertEqual(Article.objects.get(text__exact='The quick brown fox jumps over the lazy dog.'), a) 69 | 70 | self.assertEqual(Article.objects.get(text__contains='quick brown fox'), a) 71 | 72 | def test_ipaddress_on_postgresql(self): 73 | """ 74 | Regression test for #708 75 | 76 | "like" queries on IP address fields require casting with HOST() (on PostgreSQL). 77 | """ 78 | a = Article(name='IP test', text='The body', submitted_from='192.0.2.100') 79 | a.save() 80 | self.assertEqual(repr(Article.objects.filter(submitted_from__contains='192.0.2')), 81 | repr([a])) 82 | # Test that the searches do not match the subnet mask (/32 in this case) 83 | self.assertEqual(Article.objects.filter(submitted_from__contains='32').count(), 0) -------------------------------------------------------------------------------- /tests/django20/select_related_onetoone/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils.encoding import python_2_unicode_compatible 3 | 4 | 5 | @python_2_unicode_compatible 6 | class User(models.Model): 7 | username = models.CharField(max_length=100) 8 | email = models.EmailField() 9 | 10 | def __str__(self): 11 | return self.username 12 | 13 | 14 | @python_2_unicode_compatible 15 | class UserProfile(models.Model): 16 | user = models.OneToOneField(User) 17 | city = models.CharField(max_length=100) 18 | state = models.CharField(max_length=2) 19 | 20 | def __str__(self): 21 | return "%s, %s" % (self.city, self.state) 22 | 23 | 24 | @python_2_unicode_compatible 25 | class UserStatResult(models.Model): 26 | results = models.CharField(max_length=50) 27 | 28 | def __str__(self): 29 | return 'UserStatResults, results = %s' % (self.results,) 30 | 31 | 32 | @python_2_unicode_compatible 33 | class UserStat(models.Model): 34 | user = models.OneToOneField(User, primary_key=True) 35 | posts = models.IntegerField() 36 | results = models.ForeignKey(UserStatResult) 37 | 38 | def __str__(self): 39 | return 'UserStat, posts = %s' % (self.posts,) 40 | 41 | 42 | @python_2_unicode_compatible 43 | class StatDetails(models.Model): 44 | base_stats = models.OneToOneField(UserStat) 45 | comments = models.IntegerField() 46 | 47 | def __str__(self): 48 | return 'StatDetails, comments = %s' % (self.comments,) 49 | 50 | 51 | class AdvancedUserStat(UserStat): 52 | karma = models.IntegerField() 53 | 54 | 55 | class Image(models.Model): 56 | name = models.CharField(max_length=100) 57 | 58 | 59 | class Product(models.Model): 60 | name = models.CharField(max_length=100) 61 | image = models.OneToOneField(Image, null=True) 62 | 63 | 64 | @python_2_unicode_compatible 65 | class Parent1(models.Model): 66 | name1 = models.CharField(max_length=50) 67 | 68 | def __str__(self): 69 | return self.name1 70 | 71 | 72 | @python_2_unicode_compatible 73 | class Parent2(models.Model): 74 | # Avoid having two "id" fields in the Child1 subclass 75 | id2 = models.AutoField(primary_key=True) 76 | name2 = models.CharField(max_length=50) 77 | 78 | def __str__(self): 79 | return self.name2 80 | 81 | 82 | @python_2_unicode_compatible 83 | class Child1(Parent1, Parent2): 84 | value = models.IntegerField() 85 | 86 | def __str__(self): 87 | return self.name1 88 | 89 | 90 | @python_2_unicode_compatible 91 | class Child2(Parent1): 92 | parent2 = models.OneToOneField(Parent2) 93 | value = models.IntegerField() 94 | 95 | def __str__(self): 96 | return self.name1 97 | 98 | class Child3(Child2): 99 | value3 = models.IntegerField() 100 | 101 | class Child4(Child1): 102 | value4 = models.IntegerField() 103 | -------------------------------------------------------------------------------- /tests/django20/m2m_through_regress/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.contrib.auth.models import User 4 | from django.db import models 5 | from django.utils.encoding import python_2_unicode_compatible 6 | 7 | 8 | # Forward declared intermediate model 9 | @python_2_unicode_compatible 10 | class Membership(models.Model): 11 | person = models.ForeignKey('Person') 12 | group = models.ForeignKey('Group') 13 | price = models.IntegerField(default=100) 14 | 15 | def __str__(self): 16 | return "%s is a member of %s" % (self.person.name, self.group.name) 17 | 18 | # using custom id column to test ticket #11107 19 | @python_2_unicode_compatible 20 | class UserMembership(models.Model): 21 | id = models.AutoField(db_column='usermembership_id', primary_key=True) 22 | user = models.ForeignKey(User) 23 | group = models.ForeignKey('Group') 24 | price = models.IntegerField(default=100) 25 | 26 | def __str__(self): 27 | return "%s is a user and member of %s" % (self.user.username, self.group.name) 28 | 29 | @python_2_unicode_compatible 30 | class Person(models.Model): 31 | name = models.CharField(max_length=128) 32 | 33 | def __str__(self): 34 | return self.name 35 | 36 | @python_2_unicode_compatible 37 | class Group(models.Model): 38 | name = models.CharField(max_length=128) 39 | # Membership object defined as a class 40 | members = models.ManyToManyField(Person, through=Membership) 41 | user_members = models.ManyToManyField(User, through='UserMembership') 42 | 43 | def __str__(self): 44 | return self.name 45 | 46 | # A set of models that use an non-abstract inherited model as the 'through' model. 47 | class A(models.Model): 48 | a_text = models.CharField(max_length=20) 49 | 50 | class ThroughBase(models.Model): 51 | a = models.ForeignKey(A) 52 | b = models.ForeignKey('B') 53 | 54 | class Through(ThroughBase): 55 | extra = models.CharField(max_length=20) 56 | 57 | class B(models.Model): 58 | b_text = models.CharField(max_length=20) 59 | a_list = models.ManyToManyField(A, through=Through) 60 | 61 | 62 | # Using to_field on the through model 63 | @python_2_unicode_compatible 64 | class Car(models.Model): 65 | make = models.CharField(max_length=20, unique=True, null=True) 66 | drivers = models.ManyToManyField('Driver', through='CarDriver') 67 | 68 | def __str__(self): 69 | return "%s" % self.make 70 | 71 | @python_2_unicode_compatible 72 | class Driver(models.Model): 73 | name = models.CharField(max_length=20, unique=True, null=True) 74 | 75 | def __str__(self): 76 | return "%s" % self.name 77 | 78 | class Meta: 79 | ordering = ('name',) 80 | 81 | @python_2_unicode_compatible 82 | class CarDriver(models.Model): 83 | car = models.ForeignKey('Car', to_field='make') 84 | driver = models.ForeignKey('Driver', to_field='name') 85 | 86 | def __str__(self): 87 | return "pk=%s car=%s driver=%s" % (str(self.pk), self.car, self.driver) 88 | -------------------------------------------------------------------------------- /tests/django20/custom_columns_regress/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.core.exceptions import FieldError 4 | from django.test import TestCase 5 | 6 | from .models import Author, Article 7 | 8 | 9 | def pks(objects): 10 | """ Return pks to be able to compare lists""" 11 | return [o.pk for o in objects] 12 | 13 | class CustomColumnRegression(TestCase): 14 | 15 | def setUp(self): 16 | self.a1 = Author.objects.create(first_name='John', last_name='Smith') 17 | self.a2 = Author.objects.create(first_name='Peter', last_name='Jones') 18 | self.authors = [self.a1, self.a2] 19 | 20 | def test_basic_creation(self): 21 | art = Article(headline='Django lets you build Web apps easily', primary_author=self.a1) 22 | art.save() 23 | art.authors = [self.a1, self.a2] 24 | 25 | def test_author_querying(self): 26 | self.assertQuerysetEqual( 27 | Author.objects.all().order_by('last_name'), 28 | ['', ''] 29 | ) 30 | 31 | def test_author_filtering(self): 32 | self.assertQuerysetEqual( 33 | Author.objects.filter(first_name__exact='John'), 34 | [''] 35 | ) 36 | 37 | def test_author_get(self): 38 | self.assertEqual(self.a1, Author.objects.get(first_name__exact='John')) 39 | 40 | def test_filter_on_nonexistant_field(self): 41 | self.assertRaisesMessage( 42 | FieldError, 43 | "Cannot resolve keyword 'firstname' into field. Choices are: Author_ID, article, first_name, last_name, primary_set", 44 | Author.objects.filter, 45 | firstname__exact='John' 46 | ) 47 | 48 | def test_author_get_attributes(self): 49 | a = Author.objects.get(last_name__exact='Smith') 50 | self.assertEqual('John', a.first_name) 51 | self.assertEqual('Smith', a.last_name) 52 | self.assertRaisesMessage( 53 | AttributeError, 54 | "'Author' object has no attribute 'firstname'", 55 | getattr, 56 | a, 'firstname' 57 | ) 58 | 59 | self.assertRaisesMessage( 60 | AttributeError, 61 | "'Author' object has no attribute 'last'", 62 | getattr, 63 | a, 'last' 64 | ) 65 | 66 | def test_m2m_table(self): 67 | art = Article.objects.create(headline='Django lets you build Web apps easily', primary_author=self.a1) 68 | art.authors = self.authors 69 | self.assertQuerysetEqual( 70 | art.authors.all().order_by('last_name'), 71 | ['', ''] 72 | ) 73 | self.assertQuerysetEqual( 74 | self.a1.article_set.all(), 75 | [''] 76 | ) 77 | self.assertQuerysetEqual( 78 | art.authors.filter(last_name='Jones'), 79 | [''] 80 | ) 81 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright 2013-2017 Lionheart Software LLC 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | import re 19 | import os 20 | 21 | try: 22 | from setuptools import setup 23 | except ImportError: 24 | from distutils.core import setup 25 | 26 | with open(os.path.join(os.path.dirname(__file__), "README.rst")) as file: 27 | long_description = file.read() 28 | 29 | id_regex = re.compile(r"<\#([\w-]+)>") 30 | link_regex = re.compile(r"<(\w+)>") 31 | link_alternate_regex = re.compile(r" :target: (\w+)") 32 | 33 | long_description = id_regex.sub(r"", long_description) 34 | long_description = link_regex.sub(r"", long_description) 35 | long_description = link_regex.sub(r"", long_description) 36 | long_description = link_alternate_regex.sub(r" :target: https://github.com/lionheart/django-pyodbc/blob/master/\1", long_description) 37 | 38 | metadata = {} 39 | metadata_file = "django_pyodbc/metadata.py" 40 | exec(compile(open(metadata_file).read(), metadata_file, 'exec'), metadata) 41 | 42 | # http://pypi.python.org/pypi?:action=list_classifiers 43 | classifiers = [ 44 | "Development Status :: 5 - Production/Stable", 45 | "Environment :: Console", 46 | "Intended Audience :: Developers", 47 | "License :: OSI Approved :: Apache Software License", 48 | "License :: OSI Approved :: BSD License", 49 | "Natural Language :: English", 50 | "Operating System :: MacOS :: MacOS X", 51 | "Operating System :: OS Independent", 52 | "Operating System :: Unix", 53 | "Programming Language :: Python :: 3.9", 54 | "Topic :: Software Development :: Libraries", 55 | ] 56 | 57 | setup( 58 | name='django-pyodbc', 59 | long_description=long_description, 60 | version=metadata['__version__'], 61 | license=metadata['__license__'], 62 | maintainer=metadata['__maintainer__'], 63 | maintainer_email=metadata['__maintainer_email__'], 64 | description="Django 1.5-1.10 SQL Server backend using pyodbc.", 65 | url='https://github.com/lionheart/django-pyodbc', 66 | package_data={'': ['LICENSE', 'README.rst']}, 67 | packages=[ 68 | 'django_pyodbc', 69 | 'django_pyodbc.management', 70 | 'django_pyodbc.management.commands' 71 | ], 72 | install_requires=[ 73 | 'pyodbc>=3.0.6,<4.1', 74 | 'six>=1.15.0' 75 | ] 76 | ) 77 | -------------------------------------------------------------------------------- /tests/django20/order_with_respect_to/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from operator import attrgetter 4 | 5 | from django.test import TestCase 6 | 7 | from .models import Post, Question, Answer 8 | 9 | 10 | class OrderWithRespectToTests(TestCase): 11 | def test_basic(self): 12 | q1 = Question.objects.create(text="Which Beatle starts with the letter 'R'?") 13 | q2 = Question.objects.create(text="What is your name?") 14 | 15 | Answer.objects.create(text="John", question=q1) 16 | Answer.objects.create(text="Jonno", question=q2) 17 | Answer.objects.create(text="Paul", question=q1) 18 | Answer.objects.create(text="Paulo", question=q2) 19 | Answer.objects.create(text="George", question=q1) 20 | Answer.objects.create(text="Ringo", question=q1) 21 | 22 | # The answers will always be ordered in the order they were inserted. 23 | self.assertQuerysetEqual( 24 | q1.answer_set.all(), [ 25 | "John", "Paul", "George", "Ringo", 26 | ], 27 | attrgetter("text"), 28 | ) 29 | 30 | # We can retrieve the answers related to a particular object, in the 31 | # order they were created, once we have a particular object. 32 | a1 = Answer.objects.filter(question=q1)[0] 33 | self.assertEqual(a1.text, "John") 34 | a2 = a1.get_next_in_order() 35 | self.assertEqual(a2.text, "Paul") 36 | a4 = list(Answer.objects.filter(question=q1))[-1] 37 | self.assertEqual(a4.text, "Ringo") 38 | self.assertEqual(a4.get_previous_in_order().text, "George") 39 | 40 | # Determining (and setting) the ordering for a particular item is also 41 | # possible. 42 | id_list = [o.pk for o in q1.answer_set.all()] 43 | self.assertEqual(a2.question.get_answer_order(), id_list) 44 | 45 | a5 = Answer.objects.create(text="Number five", question=q1) 46 | 47 | # It doesn't matter which answer we use to check the order, it will 48 | # always be the same. 49 | self.assertEqual( 50 | a2.question.get_answer_order(), a5.question.get_answer_order() 51 | ) 52 | 53 | # The ordering can be altered: 54 | id_list = [o.pk for o in q1.answer_set.all()] 55 | x = id_list.pop() 56 | id_list.insert(-1, x) 57 | self.assertNotEqual(a5.question.get_answer_order(), id_list) 58 | a5.question.set_answer_order(id_list) 59 | self.assertQuerysetEqual( 60 | q1.answer_set.all(), [ 61 | "John", "Paul", "George", "Number five", "Ringo" 62 | ], 63 | attrgetter("text") 64 | ) 65 | 66 | def test_recursive_ordering(self): 67 | p1 = Post.objects.create(title='1') 68 | p2 = Post.objects.create(title='2') 69 | p1_1 = Post.objects.create(title="1.1", parent=p1) 70 | p1_2 = Post.objects.create(title="1.2", parent=p1) 71 | p2_1 = Post.objects.create(title="2.1", parent=p2) 72 | p1_3 = Post.objects.create(title="1.3", parent=p1) 73 | self.assertEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk]) 74 | -------------------------------------------------------------------------------- /tests/django20/raw_query/fixtures/raw_query_books.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "raw_query.author", 5 | "fields": { 6 | "dob": "1950-09-20", 7 | "first_name": "Joe", 8 | "last_name": "Smith" 9 | } 10 | }, 11 | { 12 | "pk": 2, 13 | "model": "raw_query.author", 14 | "fields": { 15 | "dob": "1920-04-02", 16 | "first_name": "Jill", 17 | "last_name": "Doe" 18 | } 19 | }, 20 | { 21 | "pk": 3, 22 | "model": "raw_query.author", 23 | "fields": { 24 | "dob": "1986-01-25", 25 | "first_name": "Bob", 26 | "last_name": "Smith" 27 | } 28 | }, 29 | { 30 | "pk": 4, 31 | "model": "raw_query.author", 32 | "fields": { 33 | "dob": "1932-05-10", 34 | "first_name": "Bill", 35 | "last_name": "Jones" 36 | } 37 | }, 38 | { 39 | "pk": 1, 40 | "model": "raw_query.book", 41 | "fields": { 42 | "author": 1, 43 | "title": "The awesome book", 44 | "paperback": false, 45 | "opening_line": "It was a bright cold day in April and the clocks were striking thirteen." 46 | } 47 | }, 48 | { 49 | "pk": 2, 50 | "model": "raw_query.book", 51 | "fields": { 52 | "author": 1, 53 | "title": "The horrible book", 54 | "paperback": true, 55 | "opening_line": "On an evening in the latter part of May a middle-aged man was walking homeward from Shaston to the village of Marlott, in the adjoining Vale of Blakemore, or Blackmoor." 56 | } 57 | }, 58 | { 59 | "pk": 3, 60 | "model": "raw_query.book", 61 | "fields": { 62 | "author": 1, 63 | "title": "Another awesome book", 64 | "paperback": false, 65 | "opening_line": "A squat grey building of only thirty-four stories." 66 | } 67 | }, 68 | { 69 | "pk": 4, 70 | "model": "raw_query.book", 71 | "fields": { 72 | "author": 3, 73 | "title": "Some other book", 74 | "paperback": true, 75 | "opening_line": "It was the day my grandmother exploded." 76 | } 77 | }, 78 | { 79 | "pk": 1, 80 | "model": "raw_query.coffee", 81 | "fields": { 82 | "brand": "dunkin doughnuts" 83 | } 84 | }, 85 | { 86 | "pk": 2, 87 | "model": "raw_query.coffee", 88 | "fields": { 89 | "brand": "starbucks" 90 | } 91 | }, 92 | { 93 | "pk": 1, 94 | "model": "raw_query.reviewer", 95 | "fields": { 96 | "reviewed": [ 97 | 2, 98 | 3, 99 | 4 100 | ] 101 | } 102 | }, 103 | { 104 | "pk": 2, 105 | "model": "raw_query.reviewer", 106 | "fields": { 107 | "reviewed": [] 108 | } 109 | } 110 | ] 111 | -------------------------------------------------------------------------------- /tests/django20/null_fk/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | from django.db.models import Q 4 | from django.test import TestCase 5 | 6 | from .models import (SystemDetails, Item, PropertyValue, SystemInfo, Forum, 7 | Post, Comment) 8 | 9 | 10 | class NullFkTests(TestCase): 11 | 12 | def test_null_fk(self): 13 | d = SystemDetails.objects.create(details='First details') 14 | s = SystemInfo.objects.create(system_name='First forum', system_details=d) 15 | f = Forum.objects.create(system_info=s, forum_name='First forum') 16 | p = Post.objects.create(forum=f, title='First Post') 17 | c1 = Comment.objects.create(post=p, comment_text='My first comment') 18 | c2 = Comment.objects.create(comment_text='My second comment') 19 | 20 | # Starting from comment, make sure that a .select_related(...) with a specified 21 | # set of fields will properly LEFT JOIN multiple levels of NULLs (and the things 22 | # that come after the NULLs, or else data that should exist won't). Regression 23 | # test for #7369. 24 | c = Comment.objects.select_related().get(id=c1.id) 25 | self.assertEqual(c.post, p) 26 | self.assertEqual(Comment.objects.select_related().get(id=c2.id).post, None) 27 | 28 | self.assertQuerysetEqual( 29 | Comment.objects.select_related('post__forum__system_info').all(), 30 | [ 31 | (c1.id, 'My first comment', ''), 32 | (c2.id, 'My second comment', 'None') 33 | ], 34 | transform = lambda c: (c.id, c.comment_text, repr(c.post)) 35 | ) 36 | 37 | # Regression test for #7530, #7716. 38 | self.assertTrue(Comment.objects.select_related('post').filter(post__isnull=True)[0].post is None) 39 | 40 | self.assertQuerysetEqual( 41 | Comment.objects.select_related('post__forum__system_info__system_details'), 42 | [ 43 | (c1.id, 'My first comment', ''), 44 | (c2.id, 'My second comment', 'None') 45 | ], 46 | transform = lambda c: (c.id, c.comment_text, repr(c.post)) 47 | ) 48 | 49 | def test_combine_isnull(self): 50 | item = Item.objects.create(title='Some Item') 51 | pv = PropertyValue.objects.create(label='Some Value') 52 | item.props.create(key='a', value=pv) 53 | item.props.create(key='b') # value=NULL 54 | q1 = Q(props__key='a', props__value=pv) 55 | q2 = Q(props__key='b', props__value__isnull=True) 56 | 57 | # Each of these individually should return the item. 58 | self.assertEqual(Item.objects.get(q1), item) 59 | self.assertEqual(Item.objects.get(q2), item) 60 | 61 | # Logically, qs1 and qs2, and qs3 and qs4 should be the same. 62 | qs1 = Item.objects.filter(q1) & Item.objects.filter(q2) 63 | qs2 = Item.objects.filter(q2) & Item.objects.filter(q1) 64 | qs3 = Item.objects.filter(q1) | Item.objects.filter(q2) 65 | qs4 = Item.objects.filter(q2) | Item.objects.filter(q1) 66 | 67 | # Regression test for #15823. 68 | self.assertEqual(list(qs1), list(qs2)) 69 | self.assertEqual(list(qs3), list(qs4)) 70 | -------------------------------------------------------------------------------- /tests/django20/null_queries/tests.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.test import TestCase 4 | from django.core.exceptions import FieldError 5 | 6 | from .models import Poll, Choice, OuterA, Inner, OuterB 7 | 8 | 9 | class NullQueriesTests(TestCase): 10 | 11 | def test_none_as_null(self): 12 | """ 13 | Regression test for the use of None as a query value. 14 | 15 | None is interpreted as an SQL NULL, but only in __exact queries. 16 | Set up some initial polls and choices 17 | """ 18 | p1 = Poll(question='Why?') 19 | p1.save() 20 | c1 = Choice(poll=p1, choice='Because.') 21 | c1.save() 22 | c2 = Choice(poll=p1, choice='Why Not?') 23 | c2.save() 24 | 25 | # Exact query with value None returns nothing ("is NULL" in sql, 26 | # but every 'id' field has a value). 27 | self.assertQuerysetEqual(Choice.objects.filter(choice__exact=None), []) 28 | 29 | # Excluding the previous result returns everything. 30 | self.assertQuerysetEqual( 31 | Choice.objects.exclude(choice=None).order_by('id'), 32 | [ 33 | '', 34 | '' 35 | ] 36 | ) 37 | 38 | # Valid query, but fails because foo isn't a keyword 39 | self.assertRaises(FieldError, Choice.objects.filter, foo__exact=None) 40 | 41 | # Can't use None on anything other than __exact 42 | self.assertRaises(ValueError, Choice.objects.filter, id__gt=None) 43 | 44 | # Can't use None on anything other than __exact 45 | self.assertRaises(ValueError, Choice.objects.filter, foo__gt=None) 46 | 47 | # Related managers use __exact=None implicitly if the object hasn't been saved. 48 | p2 = Poll(question="How?") 49 | self.assertEqual(repr(p2.choice_set.all()), '[]') 50 | 51 | def test_reverse_relations(self): 52 | """ 53 | Querying across reverse relations and then another relation should 54 | insert outer joins correctly so as not to exclude results. 55 | """ 56 | obj = OuterA.objects.create() 57 | self.assertQuerysetEqual( 58 | OuterA.objects.filter(inner__third=None), 59 | [''] 60 | ) 61 | self.assertQuerysetEqual( 62 | OuterA.objects.filter(inner__third__data=None), 63 | [''] 64 | ) 65 | 66 | inner_obj = Inner.objects.create(first=obj) 67 | self.assertQuerysetEqual( 68 | Inner.objects.filter(first__inner__third=None), 69 | [''] 70 | ) 71 | 72 | # Ticket #13815: check if _isnull=False does not produce 73 | # faulty empty lists 74 | objB = OuterB.objects.create(data="reverse") 75 | self.assertQuerysetEqual( 76 | OuterB.objects.filter(inner__isnull=False), 77 | [] 78 | ) 79 | Inner.objects.create(first=obj) 80 | self.assertQuerysetEqual( 81 | OuterB.objects.exclude(inner__isnull=False), 82 | [''] 83 | ) 84 | -------------------------------------------------------------------------------- /tests/test_django_pyodbc.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008, django-pyodbc developers (see README.rst). 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of django-sql-server nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # This is an example test settings file for use with the Django test suite. 30 | # 31 | # The 'sqlite3' backend requires only the ENGINE setting (an in- 32 | # memory database will be used). All other backends will require a 33 | # NAME and potentially authentication information. See the 34 | # following section in the docs for more information: 35 | # 36 | # https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/ 37 | # 38 | # The different databases that Django supports behave differently in certain 39 | # situations, so it is recommended to run the test suite against as many 40 | # database backends as possible. You may want to create a separate settings 41 | # file for each of the backends you test against. 42 | 43 | 44 | DATABASES = { 45 | 'default': { 46 | 'ENGINE': "django_pyodbc", 47 | 'HOST': "127.0.0.1\SQLEXPRESS,1433", 48 | 'USER': "sa", 49 | 'PASSWORD': "1Password", 50 | 'NAME': "defaultdb", 51 | 'OPTIONS': { 52 | 'host_is_server': True, 53 | 'autocommit': True, 54 | 'driver': "SQL Server Native Client 11.0" 55 | }, 56 | }, 57 | 'other': { 58 | 'ENGINE': "django_pyodbc", 59 | 'HOST': "127.0.0.1\SQLEXPRESS,1433", 60 | 'USER': "sa", 61 | 'PASSWORD': "1Password", 62 | 'NAME': "otherdb", 63 | 'OPTIONS': { 64 | 'host_is_server': True, 65 | 'autocommit': True, 66 | 'driver': "SQL Server Native Client 11.0" 67 | }, 68 | }, 69 | } 70 | 71 | SECRET_KEY = "django_tests_secret_key" 72 | 73 | # Use a fast hasher to speed up tests. 74 | PASSWORD_HASHERS = ( 75 | 'django.contrib.auth.hashers.MD5PasswordHasher', 76 | ) 77 | -------------------------------------------------------------------------------- /tests/django20/aggregation_regress/models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from django.contrib.contenttypes import generic 3 | from django.contrib.contenttypes.models import ContentType 4 | from django.db import models 5 | from django.utils.encoding import python_2_unicode_compatible 6 | 7 | 8 | @python_2_unicode_compatible 9 | class Author(models.Model): 10 | name = models.CharField(max_length=100) 11 | age = models.IntegerField() 12 | friends = models.ManyToManyField('self', blank=True) 13 | 14 | def __str__(self): 15 | return self.name 16 | 17 | 18 | @python_2_unicode_compatible 19 | class Publisher(models.Model): 20 | name = models.CharField(max_length=255) 21 | num_awards = models.IntegerField() 22 | 23 | def __str__(self): 24 | return self.name 25 | 26 | 27 | class ItemTag(models.Model): 28 | tag = models.CharField(max_length=100) 29 | content_type = models.ForeignKey(ContentType) 30 | object_id = models.PositiveIntegerField() 31 | content_object = generic.GenericForeignKey('content_type', 'object_id') 32 | 33 | 34 | @python_2_unicode_compatible 35 | class Book(models.Model): 36 | isbn = models.CharField(max_length=9) 37 | name = models.CharField(max_length=255) 38 | pages = models.IntegerField() 39 | rating = models.FloatField() 40 | price = models.DecimalField(decimal_places=2, max_digits=6) 41 | authors = models.ManyToManyField(Author) 42 | contact = models.ForeignKey(Author, related_name='book_contact_set') 43 | publisher = models.ForeignKey(Publisher) 44 | pubdate = models.DateField() 45 | tags = generic.GenericRelation(ItemTag) 46 | 47 | class Meta: 48 | ordering = ('name',) 49 | 50 | def __str__(self): 51 | return self.name 52 | 53 | 54 | @python_2_unicode_compatible 55 | class Store(models.Model): 56 | name = models.CharField(max_length=255) 57 | books = models.ManyToManyField(Book) 58 | original_opening = models.DateTimeField() 59 | friday_night_closing = models.TimeField() 60 | 61 | def __str__(self): 62 | return self.name 63 | 64 | class Entries(models.Model): 65 | EntryID = models.AutoField(primary_key=True, db_column='Entry ID') 66 | Entry = models.CharField(unique=True, max_length=50) 67 | Exclude = models.BooleanField(default=False) 68 | 69 | 70 | class Clues(models.Model): 71 | ID = models.AutoField(primary_key=True) 72 | EntryID = models.ForeignKey(Entries, verbose_name='Entry', db_column = 'Entry ID') 73 | Clue = models.CharField(max_length=150) 74 | 75 | 76 | class WithManualPK(models.Model): 77 | # The generic relations regression test needs two different model 78 | # classes with the same PK value, and there are some (external) 79 | # DB backends that don't work nicely when assigning integer to AutoField 80 | # column (MSSQL at least). 81 | id = models.IntegerField(primary_key=True) 82 | 83 | 84 | @python_2_unicode_compatible 85 | class HardbackBook(Book): 86 | weight = models.FloatField() 87 | 88 | def __str__(self): 89 | return "%s (hardback): %s" % (self.name, self.weight) 90 | 91 | # Models for ticket #21150 92 | class Alfa(models.Model): 93 | pass 94 | 95 | class Bravo(models.Model): 96 | pass 97 | 98 | class Charlie(models.Model): 99 | alfa = models.ForeignKey(Alfa, null=True) 100 | bravo = models.ForeignKey(Bravo, null=True) 101 | -------------------------------------------------------------------------------- /tests/django20/delete_regress/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.contenttypes import generic 2 | from django.contrib.contenttypes.models import ContentType 3 | from django.db import models 4 | 5 | class Award(models.Model): 6 | name = models.CharField(max_length=25) 7 | object_id = models.PositiveIntegerField() 8 | content_type = models.ForeignKey(ContentType) 9 | content_object = generic.GenericForeignKey() 10 | 11 | class AwardNote(models.Model): 12 | award = models.ForeignKey(Award) 13 | note = models.CharField(max_length=100) 14 | 15 | class Person(models.Model): 16 | name = models.CharField(max_length=25) 17 | awards = generic.GenericRelation(Award) 18 | 19 | class Book(models.Model): 20 | pagecount = models.IntegerField() 21 | 22 | class Toy(models.Model): 23 | name = models.CharField(max_length=50) 24 | 25 | class Child(models.Model): 26 | name = models.CharField(max_length=50) 27 | toys = models.ManyToManyField(Toy, through='PlayedWith') 28 | 29 | class PlayedWith(models.Model): 30 | child = models.ForeignKey(Child) 31 | toy = models.ForeignKey(Toy) 32 | date = models.DateField(db_column='date_col') 33 | 34 | class PlayedWithNote(models.Model): 35 | played = models.ForeignKey(PlayedWith) 36 | note = models.TextField() 37 | 38 | class Contact(models.Model): 39 | label = models.CharField(max_length=100) 40 | 41 | class Email(Contact): 42 | email_address = models.EmailField(max_length=100) 43 | 44 | class Researcher(models.Model): 45 | contacts = models.ManyToManyField(Contact, related_name="research_contacts") 46 | 47 | class Food(models.Model): 48 | name = models.CharField(max_length=20, unique=True) 49 | 50 | class Eaten(models.Model): 51 | food = models.ForeignKey(Food, to_field="name") 52 | meal = models.CharField(max_length=20) 53 | 54 | 55 | # Models for #15776 56 | 57 | class Policy(models.Model): 58 | policy_number = models.CharField(max_length=10) 59 | 60 | class Version(models.Model): 61 | policy = models.ForeignKey(Policy) 62 | 63 | class Location(models.Model): 64 | version = models.ForeignKey(Version, blank=True, null=True) 65 | 66 | class Item(models.Model): 67 | version = models.ForeignKey(Version) 68 | location = models.ForeignKey(Location, blank=True, null=True) 69 | 70 | # Models for #16128 71 | 72 | class File(models.Model): 73 | pass 74 | 75 | class Image(File): 76 | class Meta: 77 | proxy = True 78 | 79 | class Photo(Image): 80 | class Meta: 81 | proxy = True 82 | 83 | class FooImage(models.Model): 84 | my_image = models.ForeignKey(Image) 85 | 86 | class FooFile(models.Model): 87 | my_file = models.ForeignKey(File) 88 | 89 | class FooPhoto(models.Model): 90 | my_photo = models.ForeignKey(Photo) 91 | 92 | class FooFileProxy(FooFile): 93 | class Meta: 94 | proxy = True 95 | 96 | class OrgUnit(models.Model): 97 | name = models.CharField(max_length=64, unique=True) 98 | 99 | class Login(models.Model): 100 | description = models.CharField(max_length=32) 101 | orgunit = models.ForeignKey(OrgUnit) 102 | 103 | class House(models.Model): 104 | address = models.CharField(max_length=32) 105 | 106 | class OrderedPerson(models.Model): 107 | name = models.CharField(max_length=32) 108 | lives_in = models.ForeignKey(House) 109 | 110 | class Meta: 111 | ordering = ['name'] 112 | -------------------------------------------------------------------------------- /tests/django20/select_related_regress/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.utils.encoding import python_2_unicode_compatible 5 | 6 | 7 | @python_2_unicode_compatible 8 | class Building(models.Model): 9 | name = models.CharField(max_length=10) 10 | 11 | def __str__(self): 12 | return "Building: %s" % self.name 13 | 14 | @python_2_unicode_compatible 15 | class Device(models.Model): 16 | building = models.ForeignKey('Building') 17 | name = models.CharField(max_length=10) 18 | 19 | def __str__(self): 20 | return "device '%s' in building %s" % (self.name, self.building) 21 | 22 | @python_2_unicode_compatible 23 | class Port(models.Model): 24 | device = models.ForeignKey('Device') 25 | port_number = models.CharField(max_length=10) 26 | 27 | def __str__(self): 28 | return "%s/%s" % (self.device.name, self.port_number) 29 | 30 | @python_2_unicode_compatible 31 | class Connection(models.Model): 32 | start = models.ForeignKey(Port, related_name='connection_start', 33 | unique=True) 34 | end = models.ForeignKey(Port, related_name='connection_end', unique=True) 35 | 36 | def __str__(self): 37 | return "%s to %s" % (self.start, self.end) 38 | 39 | # Another non-tree hierarchy that exercises code paths similar to the above 40 | # example, but in a slightly different configuration. 41 | class TUser(models.Model): 42 | name = models.CharField(max_length=200) 43 | 44 | class Person(models.Model): 45 | user = models.ForeignKey(TUser, unique=True) 46 | 47 | class Organizer(models.Model): 48 | person = models.ForeignKey(Person) 49 | 50 | class Student(models.Model): 51 | person = models.ForeignKey(Person) 52 | 53 | class Class(models.Model): 54 | org = models.ForeignKey(Organizer) 55 | 56 | class Enrollment(models.Model): 57 | std = models.ForeignKey(Student) 58 | cls = models.ForeignKey(Class) 59 | 60 | # Models for testing bug #8036. 61 | class Country(models.Model): 62 | name = models.CharField(max_length=50) 63 | 64 | class State(models.Model): 65 | name = models.CharField(max_length=50) 66 | country = models.ForeignKey(Country) 67 | 68 | class ClientStatus(models.Model): 69 | name = models.CharField(max_length=50) 70 | 71 | class Client(models.Model): 72 | name = models.CharField(max_length=50) 73 | state = models.ForeignKey(State, null=True) 74 | status = models.ForeignKey(ClientStatus) 75 | 76 | class SpecialClient(Client): 77 | value = models.IntegerField() 78 | 79 | # Some model inheritance exercises 80 | @python_2_unicode_compatible 81 | class Parent(models.Model): 82 | name = models.CharField(max_length=10) 83 | 84 | def __str__(self): 85 | return self.name 86 | 87 | class Child(Parent): 88 | value = models.IntegerField() 89 | 90 | @python_2_unicode_compatible 91 | class Item(models.Model): 92 | name = models.CharField(max_length=10) 93 | child = models.ForeignKey(Child, null=True) 94 | 95 | def __str__(self): 96 | return self.name 97 | 98 | # Models for testing bug #19870. 99 | @python_2_unicode_compatible 100 | class Fowl(models.Model): 101 | name = models.CharField(max_length=10) 102 | 103 | def __str__(self): 104 | return self.name 105 | 106 | class Hen(Fowl): 107 | pass 108 | 109 | class Chick(Fowl): 110 | mother = models.ForeignKey(Hen) 111 | -------------------------------------------------------------------------------- /django_pyodbc/aggregates.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013-2017 Lionheart Software LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Copyright (c) 2008, django-pyodbc developers (see README.rst). 16 | # All rights reserved. 17 | # 18 | # Redistribution and use in source and binary forms, with or without modification, 19 | # are permitted provided that the following conditions are met: 20 | # 21 | # 1. Redistributions of source code must retain the above copyright notice, 22 | # this list of conditions and the following disclaimer. 23 | # 24 | # 2. Redistributions in binary form must reproduce the above copyright 25 | # notice, this list of conditions and the following disclaimer in the 26 | # documentation and/or other materials provided with the distribution. 27 | # 28 | # 3. Neither the name of django-sql-server nor the names of its contributors 29 | # may be used to endorse or promote products derived from this software 30 | # without specific prior written permission. 31 | # 32 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 33 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 34 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 35 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 36 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 37 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 39 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | 43 | from django.db.models.sql.aggregates import Aggregate 44 | 45 | class _Aggregate(Aggregate): 46 | 47 | def __init__(self, lookup, **extra): 48 | self.lookup = lookup 49 | self.extra = extra 50 | 51 | def _default_alias(self): 52 | return '%s__%s' % (self.lookup, self.__class__.__name__.lower()) 53 | default_alias = property(_default_alias) 54 | 55 | def add_to_query(self, query, alias, col, source, is_summary): 56 | super(_Aggregate, self).__init__(col, source, is_summary, **self.extra) 57 | query.aggregates[alias] = self 58 | 59 | class StdDev(_Aggregate): 60 | name = 'StdDev' 61 | is_computed = True 62 | 63 | def __init__(self, col, sample=False, **extra): 64 | super(StdDev, self).__init__(col, **extra) 65 | self.sql_function = sample and 'STDEV' or 'STDEVP' 66 | 67 | class Variance(_Aggregate): 68 | name = 'Variance' 69 | is_computed = True 70 | 71 | def __init__(self, col, sample=False, **extra): 72 | super(Variance, self).__init__(col, **extra) 73 | self.sql_function = sample and 'VAR' or 'VARP' 74 | 75 | class Avg(_Aggregate): 76 | name = 'Avg' 77 | is_computed = True 78 | sql_function = 'AVG' 79 | sql_template = '%(function)s(Convert(FLOAT, %(field)s))' 80 | --------------------------------------------------------------------------------