Ejemplo n.º 1
0
    def test_regression_7110(self):
        """
        Regression test for bug #7110.

        When using select_related(), we must query the
        Device and Building tables using two different aliases (each) in order to
        differentiate the start and end Connection fields. The net result is that
        both the "connections = ..." queries here should give the same results
        without pulling in more than the absolute minimum number of tables
        (history has shown that it's easy to make a mistake in the implementation
        and include some unnecessary bonus joins).
        """

        b=Building.objects.create(name='101')
        dev1=Device.objects.create(name="router", building=b)
        dev2=Device.objects.create(name="switch", building=b)
        dev3=Device.objects.create(name="server", building=b)
        port1=Port.objects.create(port_number='4',device=dev1)
        port2=Port.objects.create(port_number='7',device=dev2)
        port3=Port.objects.create(port_number='1',device=dev3)
        c1=Connection.objects.create(start=port1, end=port2)
        c2=Connection.objects.create(start=port2, end=port3)

        connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id')
        self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections],
            [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')])

        connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id')
        self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections],
            [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')])

        # This final query should only have seven tables (port, device and building
        # twice each, plus connection once). Thus, 6 joins plus the FROM table.
        self.assertEqual(str(connections.query).count(" JOIN "), 6)
Ejemplo n.º 2
0
 def date_error_message(self, lookup_type, field, unique_for):
     opts = self._meta
     return _("%(field_name)s must be unique for %(date_field)s %(lookup)s.") % {
         "field_name": six.text_type(capfirst(opts.get_field(field).verbose_name)),
         "date_field": six.text_type(capfirst(opts.get_field(unique_for).verbose_name)),
         "lookup": lookup_type,
     }
Ejemplo n.º 3
0
    def test_change_form_deletion_when_invalid(self):
        """
        Make sure that a change form that is filled out, but marked for deletion
        doesn't cause validation errors.
        """
        PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
        poet = Poet.objects.create(name='test')
        poem = poet.poem_set.create(name='test poem')
        data = {
            'poem_set-TOTAL_FORMS': '1',
            'poem_set-INITIAL_FORMS': '1',
            'poem_set-MAX_NUM_FORMS': '0',
            'poem_set-0-id': six.text_type(poem.id),
            'poem_set-0-poem': six.text_type(poem.id),
            'poem_set-0-name': 'x' * 1000,
        }
        formset = PoemFormSet(data, instance=poet)
        # Make sure this form doesn't pass validation.
        self.assertEqual(formset.is_valid(), False)
        self.assertEqual(Poem.objects.count(), 1)

        # Then make sure that it *does* pass validation and delete the object,
        # even though the data isn't actually valid.
        data['poem_set-0-DELETE'] = 'on'
        formset = PoemFormSet(data, instance=poet)
        self.assertEqual(formset.is_valid(), True)
        formset.save()
        self.assertEqual(Poem.objects.count(), 0)
Ejemplo n.º 4
0
    def test_intermeiary(self):
        r1 = Reporter.objects.create(first_name="John", last_name="Smith")
        r2 = Reporter.objects.create(first_name="Jane", last_name="Doe")

        a = Article.objects.create(
            headline="This is a test", pub_date=datetime(2005, 7, 27)
        )

        w1 = Writer.objects.create(reporter=r1, article=a, position="Main writer")
        w2 = Writer.objects.create(reporter=r2, article=a, position="Contributor")

        self.assertQuerysetEqual(
            a.writer_set.select_related().order_by("-position"), [
                ("John Smith", "Main writer"),
                ("Jane Doe", "Contributor"),
            ],
            lambda w: (six.text_type(w.reporter), w.position)
        )
        self.assertEqual(w1.reporter, r1)
        self.assertEqual(w2.reporter, r2)

        self.assertEqual(w1.article, a)
        self.assertEqual(w2.article, a)

        self.assertQuerysetEqual(
            r1.writer_set.all(), [
                ("John Smith", "Main writer")
            ],
            lambda w: (six.text_type(w.reporter), w.position)
        )
Ejemplo n.º 5
0
    def test_abstract(self):
        # The Student and Worker models both have 'name' and 'age' fields on
        # them and inherit the __unicode__() method, just as with normal Python
        # subclassing. This is useful if you want to factor out common
        # information for programming purposes, but still completely
        # independent separate models at the database level.
        w1 = Worker.objects.create(name="Fred", age=35, job="Quarry worker")
        w2 = Worker.objects.create(name="Barney", age=34, job="Quarry worker")

        s = Student.objects.create(name="Pebbles", age=5, school_class="1B")

        self.assertEqual(six.text_type(w1), "Worker Fred")
        self.assertEqual(six.text_type(s), "Student Pebbles")

        # The children inherit the Meta class of their parents (if they don't
        # specify their own).
        self.assertQuerysetEqual(
            Worker.objects.values("name"), [
                {"name": "Barney"},
                {"name": "Fred"},
            ],
            lambda o: o
        )

        # Since Student does not subclass CommonInfo's Meta, it has the effect
        # of completely overriding it. So ordering by name doesn't take place
        # for Students.
        self.assertEqual(Student._meta.ordering, [])

        # However, the CommonInfo class cannot be used as a normal model (it
        # doesn't exist as a model).
        self.assertRaises(AttributeError, lambda: CommonInfo.objects.all())

        # A StudentWorker which does not exist is both a Student and Worker
        # which does not exist.
        self.assertRaises(Student.DoesNotExist,
            StudentWorker.objects.get, pk=12321321
        )
        self.assertRaises(Worker.DoesNotExist,
            StudentWorker.objects.get, pk=12321321
        )

        # MultipleObjectsReturned is also inherited.
        # This is written out "long form", rather than using __init__/create()
        # because of a bug with diamond inheritance (#10808)
        sw1 = StudentWorker()
        sw1.name = "Wilma"
        sw1.age = 35
        sw1.save()
        sw2 = StudentWorker()
        sw2.name = "Betty"
        sw2.age = 24
        sw2.save()

        self.assertRaises(Student.MultipleObjectsReturned,
            StudentWorker.objects.get, pk__lt=sw2.pk + 100
        )
        self.assertRaises(Worker.MultipleObjectsReturned,
            StudentWorker.objects.get, pk__lt=sw2.pk + 100
        )
Ejemplo n.º 6
0
 def test_overriding_prefetch(self):
     with self.assertNumQueries(3):
         qs = Author.objects.prefetch_related('books', 'books__read_by')
         lists = [[[six.text_type(r) for r in b.read_by.all()]
                   for b in a.books.all()]
                  for a in qs]
         self.assertEqual(lists,
         [
             [["Amy"], ["Belinda"]],  # Charlotte - Poems, Jane Eyre
             [["Amy"]],                # Anne - Poems
             [["Amy"], []],            # Emily - Poems, Wuthering Heights
             [["Amy", "Belinda"]],    # Jane - Sense and Sense
         ])
     with self.assertNumQueries(3):
         qs = Author.objects.prefetch_related('books__read_by', 'books')
         lists = [[[six.text_type(r) for r in b.read_by.all()]
                   for b in a.books.all()]
                  for a in qs]
         self.assertEqual(lists,
         [
             [["Amy"], ["Belinda"]],  # Charlotte - Poems, Jane Eyre
             [["Amy"]],                # Anne - Poems
             [["Amy"], []],            # Emily - Poems, Wuthering Heights
             [["Amy", "Belinda"]],    # Jane - Sense and Sense
         ])
Ejemplo n.º 7
0
def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Similar to smart_bytes, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    if isinstance(s, bytes):
        if encoding == 'utf-8':
            return s
        else:
            return s.decode('utf-8', errors).encode(encoding, errors)
    if strings_only and (s is None or isinstance(s, int)):
        return s
    if isinstance(s, Promise):
        return six.text_type(s).encode(encoding, errors)
    if not isinstance(s, six.string_types):
        try:
            if six.PY3:
                return six.text_type(s).encode(encoding)
            else:
                return bytes(s)
        except UnicodeEncodeError:
            if isinstance(s, Exception):
                # An Exception subclass containing non-ASCII data that doesn't
                # know how to print itself properly. We shouldn't raise a
                # further exception.
                return ' '.join([force_bytes(arg, encoding, strings_only,
                        errors) for arg in s])
            return six.text_type(s).encode(encoding, errors)
    else:
        return s.encode(encoding, errors)
Ejemplo n.º 8
0
    def get_initkwargs(cls, form_list, initial_dict=None,
            instance_dict=None, condition_dict=None, *args, **kwargs):
        """
        Creates a dict with all needed parameters for the form wizard instances.

        * `form_list` - is a list of forms. The list entries can be single form
          classes or tuples of (`step_name`, `form_class`). If you pass a list
          of forms, the wizardview will convert the class list to
          (`zero_based_counter`, `form_class`). This is needed to access the
          form for a specific step.
        * `initial_dict` - contains a dictionary of initial data dictionaries.
          The key should be equal to the `step_name` in the `form_list` (or
          the str of the zero based counter - if no step_names added in the
          `form_list`)
        * `instance_dict` - contains a dictionary whose values are model
          instances if the step is based on a ``ModelForm`` and querysets if
          the step is based on a ``ModelFormSet``. The key should be equal to
          the `step_name` in the `form_list`. Same rules as for `initial_dict`
          apply.
        * `condition_dict` - contains a dictionary of boolean values or
          callables. If the value of for a specific `step_name` is callable it
          will be called with the wizardview instance as the only argument.
          If the return value is true, the step's form will be used.
        """
        kwargs.update({
            'initial_dict': initial_dict or {},
            'instance_dict': instance_dict or {},
            'condition_dict': condition_dict or {},
        })
        init_form_list = SortedDict()

        assert len(form_list) > 0, 'at least one form is needed'

        # walk through the passed form list
        for i, form in enumerate(form_list):
            if isinstance(form, (list, tuple)):
                # if the element is a tuple, add the tuple to the new created
                # sorted dictionary.
                init_form_list[six.text_type(form[0])] = form[1]
            else:
                # if not, add the form with a zero based counter as unicode
                init_form_list[six.text_type(i)] = form

        # walk through the new created list of forms
        for form in six.itervalues(init_form_list):
            if issubclass(form, formsets.BaseFormSet):
                # if the element is based on BaseFormSet (FormSet/ModelFormSet)
                # we need to override the form variable.
                form = form.form
            # check if any form contains a FileField, if yes, we need a
            # file_storage added to the wizardview (by subclassing).
            for field in six.itervalues(form.base_fields):
                if (isinstance(field, forms.FileField) and
                        not hasattr(cls, 'file_storage')):
                    raise NoFileStorageConfigured

        # build the kwargs for the wizardview instances
        kwargs['form_list'] = init_form_list
        return kwargs
Ejemplo n.º 9
0
 def test_pickle_complex(self):
     # See ticket #16563
     x = SimpleLazyObject(complex_object)
     pickled = pickle.dumps(x)
     unpickled = pickle.loads(pickled)
     self.assertEqual(unpickled, x)
     self.assertEqual(six.text_type(unpickled), six.text_type(x))
     self.assertEqual(unpickled.name, x.name)
Ejemplo n.º 10
0
 def __str__(self):
     """
     Returns the string representation.  If GDAL is installed,
     it will be 'pretty' OGC WKT.
     """
     try:
         return six.text_type(self.srs)
     except:
         return six.text_type(self.wkt)
Ejemplo n.º 11
0
def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Similar to smart_text, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    # Handle the common case first, saves 30-40% when s is an instance of
    # six.text_type. This function gets called often in that setting.
    if isinstance(s, six.text_type):
        return s
    if strings_only and is_protected_type(s):
        return s
    try:
        if not isinstance(s, six.string_types):
            if hasattr(s, '__unicode__'):
                s = s.__unicode__()
            else:
                try:
                    if six.PY3:
                        if isinstance(s, bytes):
                            s = six.text_type(s, encoding, errors)
                        else:
                            s = six.text_type(s)
                    else:
                        s = six.text_type(bytes(s), encoding, errors)
                except UnicodeEncodeError:
                    if not isinstance(s, Exception):
                        raise
                    # If we get to here, the caller has passed in an Exception
                    # subclass populated with non-ASCII data without special
                    # handling to display as a string. We need to handle this
                    # without raising a further exception. We do an
                    # approximation to what the Exception's standard str()
                    # output should be.
                    s = ' '.join([force_text(arg, encoding, strings_only,
                            errors) for arg in s])
        else:
            # Note: We use .decode() here, instead of six.text_type(s, encoding,
            # errors), so that if s is a SafeBytes, it ends up being a
            # SafeText at the end.
            s = s.decode(encoding, errors)
    except UnicodeDecodeError as e:
        if not isinstance(s, Exception):
            raise DjangoUnicodeDecodeError(s, *e.args)
        else:
            # If we get to here, the caller has passed in an Exception
            # subclass populated with non-ASCII bytestring data without a
            # working unicode method. Try to handle this without raising a
            # further exception by individually forcing the exception args
            # to unicode.
            s = ' '.join([force_text(arg, encoding, strings_only,
                    errors) for arg in s])
    return s
Ejemplo n.º 12
0
def linenumbers(value, autoescape=None):
    """Displays text with line numbers."""
    lines = value.split('\n')
    # Find the maximum width of the line count, for use with zero padding
    # string format command
    width = six.text_type(len(six.text_type(len(lines))))
    if not autoescape or isinstance(value, SafeData):
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width  + "d. %s") % (i + 1, line)
    else:
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width  + "d. %s") % (i + 1, escape(line))
    return mark_safe('\n'.join(lines))
Ejemplo n.º 13
0
 def test_tuple_list_display(self):
     """
     Regression test for #17128
     (ChangeList failing under Python 2.5 after r16319)
     """
     swallow = Swallow.objects.create(
         origin='Africa', load='12.34', speed='22.2')
     model_admin = SwallowAdmin(Swallow, admin.site)
     superuser = self._create_superuser('superuser')
     request = self._mocked_authenticated_request('/swallow/', superuser)
     response = model_admin.changelist_view(request)
     # just want to ensure it doesn't blow up during rendering
     self.assertContains(response, six.text_type(swallow.origin))
     self.assertContains(response, six.text_type(swallow.load))
     self.assertContains(response, six.text_type(swallow.speed))
Ejemplo n.º 14
0
 def make_bytes(value):
     if isinstance(value, int):
         value = six.text_type(value)
     if isinstance(value, six.text_type):
         value = value.encode('ascii')
     # force conversion to bytes in case chunk is a subclass
     return bytes(value)
Ejemplo n.º 15
0
 def __mod__(self, rhs):
     if self._delegate_bytes and not six.PY3:
         return bytes(self) % rhs
     elif self._delegate_text:
         return six.text_type(self) % rhs
     else:
         raise AssertionError('__mod__ not supported for non-string types')
Ejemplo n.º 16
0
def format_organisation_number(gd):
    if gd['century'] is None:
        century = ''
    else:
        century = gd['century']

    return six.text_type(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
Ejemplo n.º 17
0
    def test_save_as_new_with_new_inlines(self):
        """
        Existing and new inlines are saved with save_as_new.

        Regression for #14938.

        """
        efnet = Network.objects.create(name="EFNet")
        host1 = Host.objects.create(hostname="irc.he.net", network=efnet)

        HostFormSet = inlineformset_factory(Network, Host)

        # Add a new host, modify previous host, and save-as-new
        data = {
            'host_set-TOTAL_FORMS': '2',
            'host_set-INITIAL_FORMS': '1',
            'host_set-MAX_NUM_FORMS': '0',
            'host_set-0-id': six.text_type(host1.id),
            'host_set-0-hostname': 'tranquility.hub.dal.net',
            'host_set-1-hostname': 'matrix.de.eu.dal.net'
        }

        # To save a formset as new, it needs a new hub instance
        dalnet = Network.objects.create(name="DALnet")
        formset = HostFormSet(data, instance=dalnet, save_as_new=True)

        self.assertTrue(formset.is_valid())
        formset.save()
        self.assertQuerysetEqual(
            dalnet.host_set.order_by("hostname"),
            ["<Host: matrix.de.eu.dal.net>", "<Host: tranquility.hub.dal.net>"]
            )
Ejemplo n.º 18
0
 def get_date_error_message(self, date_check):
     return ugettext("Please correct the duplicate data for %(field_name)s "
         "which must be unique for the %(lookup)s in %(date_field)s.") % {
         'field_name': date_check[2],
         'date_field': date_check[3],
         'lookup': six.text_type(date_check[1]),
     }
Ejemplo n.º 19
0
 def as_table(self):
     "Returns this formset rendered as HTML <tr>s -- excluding the <table></table>."
     # XXX: there is no semantic division between forms here, there
     # probably should be. It might make sense to render each form as a
     # table row with each field as a td.
     forms = ' '.join([form.as_table() for form in self])
     return mark_safe('\n'.join([six.text_type(self.management_form), forms]))
Ejemplo n.º 20
0
    def test_no_empty_option(self):
        "If a model's ForeignKey has blank=False and a default, no empty option is created (Refs #10792)."
        option = ChoiceOptionModel.objects.create(name='default')

        choices = list(ChoiceFieldForm().fields['choice'].choices)
        self.assertEqual(len(choices), 1)
        self.assertEqual(choices[0], (option.pk, six.text_type(option)))
Ejemplo n.º 21
0
 def __next__(self):
     chunk = next(self._iterator)
     if isinstance(chunk, int):
         chunk = six.text_type(chunk)
     if isinstance(chunk, six.text_type):
         chunk = chunk.encode(self._charset)
     # force conversion to bytes in case chunk is a subclass
     return bytes(chunk)
Ejemplo n.º 22
0
def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
    """Expected simple_unlimited_args_kwargs __doc__"""
    # Sort the dictionary by key to guarantee the order for testing.
    sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0))
    return "simple_unlimited_args_kwargs - Expected result: %s / %s" % (
        ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
        ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
        )
Ejemplo n.º 23
0
 def value_to_db_datetime(self, value):
     """
     Transform a datetime value to an object compatible with what is expected
     by the backend driver for datetime columns.
     """
     if value is None:
         return None
     return six.text_type(value)
Ejemplo n.º 24
0
    def test_full_clear(self):
        """
        Integration happy-path test that a model FileField can actually be set
        and cleared via a ModelForm.

        """
        form = DocumentForm()
        self.assertTrue('name="myfile"' in six.text_type(form))
        self.assertTrue('myfile-clear' not in six.text_type(form))
        form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')})
        self.assertTrue(form.is_valid())
        doc = form.save(commit=False)
        self.assertEqual(doc.myfile.name, 'something.txt')
        form = DocumentForm(instance=doc)
        self.assertTrue('myfile-clear' in six.text_type(form))
        form = DocumentForm(instance=doc, data={'myfile-clear': 'true'})
        doc = form.save(commit=False)
        self.assertEqual(bool(doc.myfile), False)
Ejemplo n.º 25
0
    def test_m2m_to_inheriting_model(self):
        qs = AuthorWithAge.objects.prefetch_related('books_with_year')
        with self.assertNumQueries(2):
            lst = [[six.text_type(book) for book in author.books_with_year.all()]
                   for author in qs]
        qs = AuthorWithAge.objects.all()
        lst2 = [[six.text_type(book) for book in author.books_with_year.all()]
                for author in qs]
        self.assertEqual(lst, lst2)

        qs = BookWithYear.objects.prefetch_related('aged_authors')
        with self.assertNumQueries(2):
            lst = [[six.text_type(author) for author in book.aged_authors.all()]
                   for book in qs]
        qs = BookWithYear.objects.all()
        lst2 = [[six.text_type(author) for author in book.aged_authors.all()]
               for book in qs]
        self.assertEqual(lst, lst2)
Ejemplo n.º 26
0
    def _checksum(self, value):
        chars = '0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ'

        s = sum(i * chars.index(c) for i, c in zip(reversed(range(19)), value))
        checksum = 10 - s % 10

        if checksum == 10:
            return '0'
        return six.text_type(checksum)
Ejemplo n.º 27
0
    def value_to_db_time(self, value):
        if value is None:
            return None

        # SQLite doesn't support tz-aware datetimes
        if timezone.is_aware(value):
            raise ValueError("SQLite backend does not support timezone-aware times.")

        return six.text_type(value)
Ejemplo n.º 28
0
def build_request_repr(request, path_override=None, GET_override=None,
                       POST_override=None, COOKIES_override=None,
                       META_override=None):
    """
    Builds and returns the request's representation string. The request's
    attributes may be overridden by pre-processed values.
    """
    # Since this is called as part of error handling, we need to be very
    # robust against potentially malformed input.
    try:
        get = (pformat(GET_override)
               if GET_override is not None
               else pformat(request.GET))
    except Exception:
        get = '<could not parse>'
    if request._post_parse_error:
        post = '<could not parse>'
    else:
        try:
            post = (pformat(POST_override)
                    if POST_override is not None
                    else pformat(request.POST))
        except Exception:
            post = '<could not parse>'
    try:
        cookies = (pformat(COOKIES_override)
                   if COOKIES_override is not None
                   else pformat(request.COOKIES))
    except Exception:
        cookies = '<could not parse>'
    try:
        meta = (pformat(META_override)
                if META_override is not None
                else pformat(request.META))
    except Exception:
        meta = '<could not parse>'
    path = path_override if path_override is not None else request.path
    return force_str('<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
                     (request.__class__.__name__,
                      path,
                      six.text_type(get),
                      six.text_type(post),
                      six.text_type(cookies),
                      six.text_type(meta)))
Ejemplo n.º 29
0
    def assertHTMLEqual(self, html1, html2, msg=None):
        """
        Asserts that two HTML snippets are semantically the same.
        Whitespace in most cases is ignored, and attribute ordering is not
        significant. The passed-in arguments must be valid HTML.
        """
        dom1 = assert_and_parse_html(self, html1, msg,
            'First argument is not valid HTML:')
        dom2 = assert_and_parse_html(self, html2, msg,
            'Second argument is not valid HTML:')

        if dom1 != dom2:
            standardMsg = '%s != %s' % (
                safe_repr(dom1, True), safe_repr(dom2, True))
            diff = ('\n' + '\n'.join(difflib.ndiff(
                           six.text_type(dom1).splitlines(),
                           six.text_type(dom2).splitlines())))
            standardMsg = self._truncateMessage(standardMsg, diff)
            self.fail(self._formatMessage(msg, standardMsg))
Ejemplo n.º 30
0
 def test_get(self):
     """
     Test that objects retrieved with .get() get the prefetch behavior.
     """
     # Need a double
     with self.assertNumQueries(3):
         author = Author.objects.prefetch_related('books__read_by').get(name="Charlotte")
         lists = [[six.text_type(r) for r in b.read_by.all()]
                   for b in author.books.all()]
         self.assertEqual(lists, [["Amy"], ["Belinda"]])  # Poems, Jane Eyre