def test_basic(self): a1 = Article.objects.create( title='How to Django', text=lorem_ipsum, written=timezone.now(), ) a2 = Article.objects.create( title='How to Time Travel', text=lorem_ipsum, written=timezone.now(), ) num_updated = Article.objects.filter( id=a1.id, published=None).update(published=Now()) self.assertEqual(num_updated, 1) num_updated = Article.objects.filter( id=a1.id, published=None).update(published=Now()) self.assertEqual(num_updated, 0) a1.refresh_from_db() self.assertIsInstance(a1.published, datetime) a2.published = Now() + timedelta(days=2) a2.save() a2.refresh_from_db() self.assertIsInstance(a2.published, datetime) self.assertQuerysetEqual(Article.objects.filter(published__lte=Now()), ['How to Django'], lambda a: a.title) self.assertQuerysetEqual(Article.objects.filter(published__gt=Now()), ['How to Time Travel'], lambda a: a.title)
def test_dates(self): instance = DateTimeArrayModel( datetimes=[timezone.now()], dates=[timezone.now().date()], times=[timezone.now().time()], ) instance.save() loaded = DateTimeArrayModel.objects.get() self.assertEqual(instance.datetimes, loaded.datetimes) self.assertEqual(instance.dates, loaded.dates) self.assertEqual(instance.times, loaded.times)
def test_annotate_textfield(self): Article.objects.create( title='How to Django', text='This is about How to Django.', written=timezone.now(), ) Article.objects.create( title='How to Tango', text="Won't find anything here.", written=timezone.now(), ) articles = Article.objects.annotate(title_pos=StrIndex('text', 'title')) self.assertQuerysetEqual(articles.order_by('title'), [15, 0], lambda a: a.title_pos)
def test_basic(self): now = timezone.now() before = now - timedelta(hours=1) Article.objects.create(title='Testing with Django', written=before, published=now) articles = Article.objects.annotate( last_updated=Greatest('written', 'published')) self.assertEqual(articles.first().last_updated, now)
def test_coalesce_workaround(self): past = datetime(1900, 1, 1) now = timezone.now() Article.objects.create(title='Testing with Django', written=now) articles = Article.objects.annotate(last_updated=Greatest( Coalesce('written', past), Coalesce('published', past), ), ) self.assertEqual(articles.first().last_updated, now)
class Article(models.Model): title = models.CharField(max_length=100) pub_date = models.DateField() pub_datetime = models.DateTimeField(default=timezone.now()) categories = models.ManyToManyField("Category", related_name="articles") def __str__(self): return self.title
def test_coalesce_workaround_mysql(self): future = datetime(2100, 1, 1) now = timezone.now() Article.objects.create(title='Testing with Django', written=now) future_sql = RawSQL("cast(%s as datetime)", (future, )) articles = Article.objects.annotate(last_updated=Least( Coalesce('written', future_sql), Coalesce('published', future_sql), ), ) self.assertEqual(articles.first().last_updated, now)
def setUp(self): now = timezone.now() self.datetimes = [now] self.dates = [now.date()] self.times = [now.time()] self.objs = [ DateTimeArrayModel.objects.create( datetimes=self.datetimes, dates=self.dates, times=self.times, ) ]
def test_mixed_char_text(self): Article.objects.create(title='The Title', text=lorem_ipsum, written=timezone.now()) article = Article.objects.annotate( title_text=Concat('title', V(' - '), 'text', output_field=TextField()), ).get(title='The Title') self.assertEqual(article.title + ' - ' + article.text, article.title_text) # Wrap the concat in something else to ensure that text is returned # rather than bytes. article = Article.objects.annotate( title_text=Upper(Concat('title', V(' - '), 'text', output_field=TextField())), ).get(title='The Title') expected = article.title + ' - ' + article.text self.assertEqual(expected.upper(), article.title_text)
def get_many(self, keys, version=None): if not keys: return {} key_map = {} for key in keys: self.validate_key(key) key_map[self.make_key(key, version)] = key db = router.db_for_read(self.cache_model_class) connection = connections[db] quote_name = connection.ops.quote_name table = quote_name(self._table) with connection.cursor() as cursor: cursor.execute( 'SELECT %s, %s, %s FROM %s WHERE %s IN (%s)' % ( quote_name('cache_key'), quote_name('value'), quote_name('expires'), table, quote_name('cache_key'), ', '.join(['%s'] * len(key_map)), ), list(key_map), ) rows = cursor.fetchall() result = {} expired_keys = [] expression = models.Expression(output_field=models.DateTimeField()) converters = (connection.ops.get_db_converters(expression) + expression.get_db_converters(connection)) for key, value, expires in rows: for converter in converters: if func_supports_parameter( converter, 'context'): # RemovedInDjango30Warning expires = converter(expires, expression, connection, {}) else: expires = converter(expires, expression, connection) if expires < timezone.now(): expired_keys.append(key) else: value = connection.ops.process_clob(value) value = pickle.loads(base64.b64decode(value.encode())) result[key_map.get(key)] = value self._base_delete_many(expired_keys) return result
def test_all_fields(self): now = timezone.now() instance = RangesModel( ints=NumericRange(0, 10), bigints=NumericRange(10, 20), floats=NumericRange(20, 30), timestamps=DateTimeTZRange(now - datetime.timedelta(hours=1), now), dates=DateRange(now.date() - datetime.timedelta(days=1), now.date()), ) instance.save() loaded = RangesModel.objects.get() self.assertEqual(instance.ints, loaded.ints) self.assertEqual(instance.bigints, loaded.bigints) self.assertEqual(instance.floats, loaded.floats) self.assertEqual(instance.timestamps, loaded.timestamps) self.assertEqual(instance.dates, loaded.dates)
def test_decimal_max_digits_has_no_effect(self): Book.objects.all().delete() a1 = Author.objects.first() p1 = Publisher.objects.first() thedate = timezone.now() for i in range(10): Book.objects.create(isbn="abcde{}".format(i), name="none", pages=10, rating=4.0, price=9999.98, contact=a1, publisher=p1, pubdate=thedate) book = Book.objects.aggregate(price_sum=Sum('price')) self.assertEqual(book['price_sum'], Decimal("99999.80"))
def test_mixed_values(self): a1 = Author.objects.create(name='John Smith', alias='smithj') a2 = Author.objects.create(name='Rhonda') ar1 = Article.objects.create( title='How to Django', text=lorem_ipsum, written=timezone.now(), ) ar1.authors.add(a1) ar1.authors.add(a2) # mixed Text and Char article = Article.objects.annotate(headline=Coalesce( 'summary', 'text', output_field=TextField()), ) self.assertQuerysetEqual(article.order_by('title'), [lorem_ipsum], lambda a: a.headline) # mixed Text and Char wrapped article = Article.objects.annotate(headline=Coalesce( Lower('summary'), Lower('text'), output_field=TextField()), ) self.assertQuerysetEqual(article.order_by('title'), [lorem_ipsum.lower()], lambda a: a.headline)
def test_adapt_unknown_value_time(self): value = timezone.now().time() self.assertEqual(self.ops.adapt_unknown_value(value), self.ops.adapt_timefield_value(value))
def _base_set(self, mode, key, value, timeout=DEFAULT_TIMEOUT): timeout = self.get_backend_timeout(timeout) db = router.db_for_write(self.cache_model_class) connection = connections[db] quote_name = connection.ops.quote_name table = quote_name(self._table) with connection.cursor() as cursor: cursor.execute("SELECT COUNT(*) FROM %s" % table) num = cursor.fetchone()[0] now = timezone.now() now = now.replace(microsecond=0) if timeout is None: exp = datetime.max elif settings.USE_TZ: exp = datetime.utcfromtimestamp(timeout) else: exp = datetime.fromtimestamp(timeout) exp = exp.replace(microsecond=0) if num > self._max_entries: self._cull(db, cursor, now) pickled = pickle.dumps(value, self.pickle_protocol) # The DB column is expecting a string, so make sure the value is a # string, not bytes. Refs #19274. b64encoded = base64.b64encode(pickled).decode('latin1') try: # Note: typecasting for datetimes is needed by some 3rd party # database backends. All core backends work without typecasting, # so be careful about changes here - test suite will NOT pick # regressions. with transaction.atomic(using=db): cursor.execute( 'SELECT %s, %s FROM %s WHERE %s = %%s' % ( quote_name('cache_key'), quote_name('expires'), table, quote_name('cache_key'), ), [key]) result = cursor.fetchone() if result: current_expires = result[1] expression = models.Expression( output_field=models.DateTimeField()) for converter in ( connection.ops.get_db_converters(expression) + expression.get_db_converters(connection)): if func_supports_parameter( converter, 'context'): # RemovedInDjango30Warning current_expires = converter( current_expires, expression, connection, {}) else: current_expires = converter( current_expires, expression, connection) exp = connection.ops.adapt_datetimefield_value(exp) if result and mode == 'touch': cursor.execute( 'UPDATE %s SET %s = %%s WHERE %s = %%s' % (table, quote_name('expires'), quote_name('cache_key')), [exp, key]) elif result and (mode == 'set' or (mode == 'add' and current_expires < now)): cursor.execute( 'UPDATE %s SET %s = %%s, %s = %%s WHERE %s = %%s' % ( table, quote_name('value'), quote_name('expires'), quote_name('cache_key'), ), [b64encoded, exp, key]) elif mode != 'touch': cursor.execute( 'INSERT INTO %s (%s, %s, %s) VALUES (%%s, %%s, %%s)' % ( table, quote_name('cache_key'), quote_name('value'), quote_name('expires'), ), [key, b64encoded, exp]) else: return False # touch failed. except DatabaseError: # To be threadsafe, updates/inserts are allowed to fail silently return False else: return True
def test_adapt_timefield_value_unaware(self): now = timezone.now() self.assertEqual(self.ops.adapt_timefield_value(now), str(now))
def as_string(self): """Return a string of the file contents.""" items = { "replaces_str": "", "initial_str": "", } imports = set() # Deconstruct operations operations = [] for operation in self.migration.operations: operation_string, operation_imports = OperationWriter( operation).serialize() imports.update(operation_imports) operations.append(operation_string) items["operations"] = "\n".join( operations) + "\n" if operations else "" # Format dependencies and write out swappable dependencies right dependencies = [] for dependency in self.migration.dependencies: if dependency[0] == "__setting__": dependencies.append( " migrations.swappable_dependency(settings.%s)," % dependency[1]) imports.add("from djmodels.conf import settings") else: dependencies.append(" %s," % self.serialize(dependency)[0]) items["dependencies"] = "\n".join( dependencies) + "\n" if dependencies else "" # Format imports nicely, swapping imports of functions from migration files # for comments migration_imports = set() for line in list(imports): if re.match(r"^import (.*)\.\d+[^\s]*$", line): migration_imports.add(line.split("import")[1].strip()) imports.remove(line) self.needs_manual_porting = True # djmodels.db.migrations is always used, but models import may not be. # If models import exists, merge it with migrations import. if "from djmodels.db import models" in imports: imports.discard("from djmodels.db import models") imports.add("from djmodels.db import migrations, models") else: imports.add("from djmodels.db import migrations") # Sort imports by the package / module to be imported (the part after # "from" in "from ... import ..." or after "import" in "import ..."). sorted_imports = sorted(imports, key=lambda i: i.split()[1]) items["imports"] = "\n".join(sorted_imports) + "\n" if imports else "" if migration_imports: items["imports"] += ( "\n\n# Functions from the following migrations need manual " "copying.\n# Move them and any dependencies into this file, " "then update the\n# RunPython operations to refer to the local " "versions:\n# %s") % "\n# ".join(sorted(migration_imports)) # If there's a replaces, make a string for it if self.migration.replaces: items['replaces_str'] = "\n replaces = %s\n" % self.serialize( self.migration.replaces)[0] # Hinting that goes into comment items.update( version=get_version(), timestamp=now().strftime("%Y-%m-%d %H:%M"), ) if self.migration.initial: items['initial_str'] = "\n initial = True\n" return MIGRATION_TEMPLATE % items
def test_21432(self): now = timezone.localtime(timezone.now().replace(microsecond=0)) Article.objects.create(title="First one", pub_date=now) qs = Article.objects.datetimes('pub_date', 'second') self.assertEqual(qs[0], now)
class Model(models.Model): field_dt = models.DateTimeField(default=now()) field_d = models.DateTimeField(default=now().date()) field_now = models.DateTimeField(default=now)
class Model(models.Model): field_dt = models.TimeField(default=now()) field_t = models.TimeField(default=now().time()) field_now = models.DateField(default=now)
def test_all_null(self): Article.objects.create(title='Testing with Django', written=timezone.now()) articles = Article.objects.annotate( last_updated=Greatest('published', 'updated')) self.assertIsNone(articles.first().last_updated)
def test_propagates_null(self): Article.objects.create(title='Testing with Django', written=timezone.now()) articles = Article.objects.annotate( first_updated=Least('written', 'published')) self.assertIsNone(articles.first().first_updated)
def test_ignores_null(self): now = timezone.now() Article.objects.create(title='Testing with Django', written=now) articles = Article.objects.annotate( last_updated=Greatest('written', 'published')) self.assertEqual(articles.first().last_updated, now)
def expensive_calculation(): expensive_calculation.num_runs += 1 return timezone.now()
def test_now(self): with override_settings(USE_TZ=True): self.assertTrue(timezone.is_aware(timezone.now())) with override_settings(USE_TZ=False): self.assertTrue(timezone.is_naive(timezone.now()))
def test_adapt_timefield_value(self): msg = 'Django does not support timezone-aware times.' with self.assertRaisesMessage(ValueError, msg): self.ops.adapt_timefield_value(timezone.make_aware(timezone.now()))