Exemplo n.º 1
0
    def test_mark_for_rollback_on_error_in_transaction(self):
        with transaction.atomic(savepoint=False):

            # Swallow the intentional error raised.
            with self.assertRaisesMessage(Exception, "Oops"):

                # Wrap in `mark_for_rollback_on_error` to check if the
                # transaction is marked broken.
                with transaction.mark_for_rollback_on_error():

                    # Ensure that we are still in a good state.
                    self.assertFalse(transaction.get_rollback())

                    raise Exception("Oops")

                # mark_for_rollback_on_error marked the transaction as broken …
                self.assertTrue(transaction.get_rollback())

            # … and further queries fail.
            msg = "You can't execute queries until the end of the 'atomic' block."
            with self.assertRaisesMessage(
                    transaction.TransactionManagementError, msg):
                Reporter.objects.create()

        # Transaction errors are reset at the end of an transaction, so this
        # should just work.
        Reporter.objects.create()
Exemplo n.º 2
0
    def post(self, request, title=None, content_pk=None):
        error_page = self.get_render(request)

        if self.content_form.is_valid() is True:
            self.content_instance = self.content_form.save()

            save_image_form(self.content_instance, self.image_form,
                            transaction)

            if transaction.get_rollback() is True:
                return error_page

            # last_url used for next page for javascript to scroll to the a tag that has that last_url
            last_url = str(
                reverse_lazy("content:edit",
                             kwargs={
                                 "title": self.post_instance.slug_title,
                                 "content_pk": self.content_instance.pk
                             }))

            return HttpResponseRedirect(
                reverse_lazy("post:edit",
                             kwargs={"title": self.post_instance.slug_title}) +
                f"?last=" + last_url)
        else:
            return error_page
Exemplo n.º 3
0
def _ctit_db_wrapper(trans_safe=False):
    '''
    Wrapper to avoid undesired actions by Django ORM when managing settings
    if only getting a setting, can use trans_safe=True, which will avoid
    throwing errors if the prior context was a broken transaction.
    Any database errors will be logged, but exception will be suppressed.
    '''
    rollback_set = None
    is_atomic = None
    try:
        if trans_safe:
            is_atomic = connection.in_atomic_block
            if is_atomic:
                rollback_set = transaction.get_rollback()
                if rollback_set:
                    logger.debug('Obtaining database settings in spite of broken transaction.')
                    transaction.set_rollback(False)
        yield
    except DBError:
        if trans_safe:
            if 'migrate' not in sys.argv and 'check_migrations' not in sys.argv:
                logger.exception('Database settings are not available, using defaults.')
        else:
            logger.exception('Error modifying something related to database settings.')
    finally:
        if trans_safe and is_atomic and rollback_set:
            transaction.set_rollback(rollback_set)
Exemplo n.º 4
0
Arquivo: tests.py Projeto: 6ft/django
 def test_force_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         # atomic block shouldn't rollback, but force it.
         self.assertFalse(transaction.get_rollback())
         transaction.set_rollback(True)
     self.assertQuerysetEqual(Reporter.objects.all(), [])
Exemplo n.º 5
0
 def test_force_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         # atomic block shouldn't rollback, but force it.
         self.assertFalse(transaction.get_rollback())
         transaction.set_rollback(True)
     self.assertSequenceEqual(Reporter.objects.all(), [])
Exemplo n.º 6
0
    def post(self, request, title=None):
        context = self.get_context(request)

        post_to_be_translated = context.get("post_to_be_translated")

        translation_already_existing_page = self.check_if_translation_exists(post_to_be_translated, request, context)

        if translation_already_existing_page:
            return translation_already_existing_page

        error_page = self.get_render(request, context)

        if self.form.is_valid() is True and self.content_form.is_valid() is True:
            new_post_instance = self.form.save()
            content_instance = self.content_form.save(post=new_post_instance)

            save_image_form(content_instance, self.image_form, transaction)

            self.marry_multi_language_posts(new_post_instance, post_to_be_translated)

            if transaction.get_rollback() is True:
                return error_page

            return HttpResponseRedirect(
                reverse_lazy("blog:post-detail", kwargs={"title": new_post_instance.title_slugified()}))
        else:
            return error_page
Exemplo n.º 7
0
def atomic_9(resquest):
    g1 = Group()
    s_info = 'atomic_9 save 1'
    g1.name = '%s %s' % (app_prefix, s_info)
    g1.save()

    with transaction.atomic():
        g2 = Group()
        s_info = 'atomic_9 save 2'
        g2.name = '%s %s' % (app_prefix, s_info)
        g2.save()

    g3 = Group()
    s_info = 'atomic_9 save 3'
    g3.name = '%s %s' % (app_prefix, s_info)
    g3.save()

    auto_commit = transaction.get_autocommit()
    #transaction.set_autocommit(auto_commit) # raising an exception, it is forbidden when atomic block is active
    #transaction.rollback() # raising an exception, it is forbidden when atomic block is active
    print("function get_autocommit() : %s" % (auto_commit, ))

    sid = transaction.savepoint()  # test
    print("save point id %s" % (sid, ))  # test
    transaction.savepoint_rollback(sid)
    transaction.clean_savepoints()

    rollback_cond = transaction.get_rollback()
    print("rollback condition is %s" % (rollback_cond, ))
    transaction.set_rollback(rollback_cond)

    raise Exception("Error 2")
Exemplo n.º 8
0
    def test_prevent_rollback(self):
        with transaction.atomic():
            Reporter.objects.create(first_name="Tintin")
            sid = transaction.savepoint()
            # trigger a database error inside an inner atomic without savepoint
            with self.assertRaises(DatabaseError):
                with transaction.atomic(savepoint=False):
                    connection.cursor().execute(
                        "SELECT no_such_col FROM transactions_reporter"
                    )
            # prevent atomic from rolling back since we're recovering manually
            self.assertTrue(transaction.get_rollback())
            transaction.set_rollback(False)
            transaction.savepoint_rollback(sid)
        self.assertQuerysetEqual(Reporter.objects.all(),
                                 ['<Reporter: Tintin>'])
        self.assertAtomicSignalCalls(
            # Enter atomic transaction block.
            enter_block_atomic_signal_call_sequence(True) +

            # Create Reporter.
            create_model_atomic_signal_call_sequence() +

            # Enter and leave atomic transaction block.
            enter_block_atomic_signal_call_sequence(False, savepoint=False) +
            leave_block_atomic_signal_call_sequence(False, False,
                                                    savepoint=False) +

            # Leave atomic transaction with recovered rollback.
            leave_block_atomic_signal_call_sequence(True, True)
        )
    def test_no_exception_commit_transaction(self):
        request = factory.post('/')

        with self.assertNumQueries(1):
            response = self.view(request)
        assert not transaction.get_rollback()
        assert response.status_code == status.HTTP_200_OK
        assert BasicModel.objects.count() == 1
Exemplo n.º 10
0
 def test_api_exception_rollback_transaction(self):
     """
     Transaction is rollbacked by our transaction atomic block.
     """
     request = factory.post('/')
     num_queries = 4 if connection.features.can_release_savepoints else 3
     with self.assertNumQueries(num_queries):
         # 1 - begin savepoint
         # 2 - insert
         # 3 - rollback savepoint
         # 4 - release savepoint
         with transaction.atomic(), transaction.atomic(using='secondary'):
             response = self.view(request)
             assert transaction.get_rollback()
             assert transaction.get_rollback(using='secondary')
     assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
     assert BasicModel.objects.count() == 0
    def test_no_exception_commit_transaction(self):
        request = factory.post("/")

        with self.assertNumQueries(1):
            response = self.view(request)
        self.assertFalse(transaction.get_rollback())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        assert BasicModel.objects.count() == 1
Exemplo n.º 12
0
    def test_no_exception_commit_transaction(self):
        request = factory.post('/')

        with self.assertNumQueries(1):
            response = self.view(request)
        assert not transaction.get_rollback()
        assert response.status_code == status.HTTP_200_OK
        assert BasicModel.objects.count() == 1
Exemplo n.º 13
0
    def test_no_exception_conmmit_transaction(self):
        request = factory.post('/')

        with self.assertNumQueries(1):
            response = self.view(request)
        self.assertFalse(transaction.get_rollback())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        assert BasicModel.objects.count() == 1
Exemplo n.º 14
0
def _ctit_db_wrapper(trans_safe=False):
    '''
    Wrapper to avoid undesired actions by Django ORM when managing settings
    if only getting a setting, can use trans_safe=True, which will avoid
    throwing errors if the prior context was a broken transaction.
    Any database errors will be logged, but exception will be suppressed.
    '''
    rollback_set = None
    is_atomic = None
    try:
        if trans_safe:
            is_atomic = connection.in_atomic_block
            if is_atomic:
                rollback_set = transaction.get_rollback()
                if rollback_set:
                    logger.debug('Obtaining database settings in spite of broken transaction.')
                    transaction.set_rollback(False)
        yield
    except DBError:
        # We want the _full_ traceback with the context
        # First we get the current call stack, which constitutes the "top",
        # it has the context up to the point where the context manager is used
        top_stack = StringIO()
        traceback.print_stack(file=top_stack)
        top_lines = top_stack.getvalue().strip('\n').split('\n')
        top_stack.close()
        # Get "bottom" stack from the local error that happened
        # inside of the "with" block this wraps
        exc_type, exc_value, exc_traceback = sys.exc_info()
        bottom_stack = StringIO()
        traceback.print_tb(exc_traceback, file=bottom_stack)
        bottom_lines = bottom_stack.getvalue().strip('\n').split('\n')
        # Glue together top and bottom where overlap is found
        bottom_cutoff = 0
        for i, line in enumerate(bottom_lines):
            if line in top_lines:
                # start of overlapping section, take overlap from bottom
                top_lines = top_lines[:top_lines.index(line)]
                bottom_cutoff = i
                break
        bottom_lines = bottom_lines[bottom_cutoff:]
        tb_lines = top_lines + bottom_lines

        tb_string = '\n'.join(
            ['Traceback (most recent call last):'] +
            tb_lines +
            ['{}: {}'.format(exc_type.__name__, str(exc_value))]
        )
        bottom_stack.close()
        # Log the combined stack
        if trans_safe:
            if 'check_migrations' not in sys.argv:
                logger.debug('Database settings are not available, using defaults, error:\n{}'.format(tb_string))
        else:
            logger.debug('Error modifying something related to database settings.\n{}'.format(tb_string))
    finally:
        if trans_safe and is_atomic and rollback_set:
            transaction.set_rollback(rollback_set)
Exemplo n.º 15
0
def savepoint_2(request):
    autocommit_flag = transaction.get_autocommit()
    print("autocommit state : %s" % (autocommit_flag, ))

    rollback_stat = transaction.get_rollback()
    print("rollback status : %s" % (rollback_stat, ))

    sid1 = transaction.savepoint()

    g1 = Group()
    s_info = 'savepoint_2 a'
    g1.name = '%s %s' % (app_prefix, s_info)
    g1.save()

    g2 = Group()
    s_info = 'savepoint_2 b'
    g2.name = '%s %s' % (app_prefix, s_info)
    g2.save()

    transaction.savepoint_commit(sid1)

    sid2 = transaction.savepoint()

    g3 = Group()
    s_info = 'savepoint_2 c'
    g3.name = '%s %s' % (app_prefix, s_info)
    g3.save()

    g4 = Group()
    s_info = 'savepoint_2 d'
    g4.name = '%s %s' % (app_prefix, s_info)
    g4.save()

    transaction.savepoint_rollback(sid2)

    sid3 = transaction.savepoint()

    g5 = Group()
    s_info = 'savepoint_2 e'
    g5.name = '%s %s' % (app_prefix, s_info)
    g5.save()

    g6 = Group()
    s_info = 'savepoint_2 f'
    g6.name = '%s %s' % (app_prefix, s_info)
    g6.save()

    transaction.savepoint_commit(sid3)

    transaction.clean_savepoints()

    raise Exception("Error")
Exemplo n.º 16
0
Arquivo: tests.py Projeto: shobull/hue
 def test_prevent_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         sid = transaction.savepoint()
         # trigger a database error inside an inner atomic without savepoint
         with self.assertRaises(DatabaseError):
             with transaction.atomic(savepoint=False):
                 connection.cursor().execute("SELECT no_such_col FROM transactions_reporter")
         # prevent atomic from rolling back since we're recovering manually
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
         transaction.savepoint_rollback(sid)
     self.assertQuerysetEqual(Reporter.objects.all(), ["<Reporter: Tintin>"])
Exemplo n.º 17
0
 def test_prevent_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         sid = transaction.savepoint()
         # trigger a database error inside an inner atomic without savepoint
         with self.assertRaises(DatabaseError), transaction.atomic(savepoint=False):
             connection.cursor().execute(
                     "SELECT no_such_col FROM transactions_reporter")
         transaction.savepoint_rollback(sid)
         # atomic block should rollback, but prevent it, as we just did it.
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
     self.assertQuerysetEqual(Reporter.objects.all(), ['<Reporter: Tintin>'])
Exemplo n.º 18
0
 def get_ticket(self):
     try:
         return self._internal_get_ticket()
     except exceptions:
         connection = connections[self.db]
         # If the transaction is in an `atomic` block, and needs a rollback,
         # we should mark the database as rolled back. This is because the
         # database backend may not prevent running SQL queries in broken
         # transactions, in which case we need to say that we have handled
         # the rollback so we can try one more time.
         if (connection.in_atomic_block
                 and transaction.get_rollback(using=self.db)):
             transaction.set_rollback(False, using=self.db)
         return self._internal_get_ticket()
Exemplo n.º 19
0
    def post(self, request, title=None):
        error_page = self.get_render(request)

        if self.content_form.is_valid() is True:
            self.content_instance = self.content_form.save(post=self.post_instance)

            save_image_form(self.content_instance, self.image_form, transaction)

            if transaction.get_rollback() is True:
                return error_page

            return HttpResponseRedirect(reverse_lazy("post:edit", kwargs={"title": self.post_instance.slug_title}))
        else:
            return error_page
Exemplo n.º 20
0
 def test_prevent_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         sid = transaction.savepoint()
         # trigger a database error inside an inner atomic without savepoint
         with self.assertRaises(DatabaseError):
             with transaction.atomic(savepoint=False):
                 connection.cursor().execute(
                         "SELECT no_such_col FROM transactions_reporter")
         # prevent atomic from rolling back since we're recovering manually
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
         transaction.savepoint_rollback(sid)
     self.assertQuerysetEqual(Reporter.objects.all(), ['<Reporter: Tintin>'])
Exemplo n.º 21
0
 def test_prevent_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         sid = transaction.savepoint()
         # trigger a database error inside an inner atomic without savepoint
         with self.assertRaises(DatabaseError):
             with transaction.atomic(savepoint=False):
                 connection.cursor().execute(
                         "SELECT no_such_col FROM transactions_reporter")
         transaction.savepoint_rollback(sid)
         # atomic block should rollback, but prevent it, as we just did it.
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
     self.assertQuerysetEqual(Reporter.objects.all(), ['<Reporter: Tintin>'])
Exemplo n.º 22
0
 def test_merged_outer_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         with transaction.atomic(savepoint=False):
             Reporter.objects.create(first_name="Archibald", last_name="Haddock")
             with six.assertRaisesRegex(self, Exception, "Oops"):
                 with transaction.atomic(savepoint=False):
                     Reporter.objects.create(first_name="Calculus")
                     raise Exception("Oops, that's his last name")
             # The third insert couldn't be roll back. Temporarily mark the
             # connection as not needing rollback to check it.
             self.assertTrue(transaction.get_rollback())
             transaction.set_rollback(False)
             self.assertEqual(Reporter.objects.count(), 3)
             transaction.set_rollback(True)
         # The second insert couldn't be roll back. Temporarily mark the
         # connection as not needing rollback to check it.
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
         self.assertEqual(Reporter.objects.count(), 3)
         transaction.set_rollback(True)
     # The first block has a savepoint and must roll back.
     self.assertQuerysetEqual(Reporter.objects.all(), [])
Exemplo n.º 23
0
Arquivo: tests.py Projeto: 6ft/django
 def test_merged_outer_rollback(self):
     with transaction.atomic():
         Reporter.objects.create(first_name="Tintin")
         with transaction.atomic(savepoint=False):
             Reporter.objects.create(first_name="Archibald", last_name="Haddock")
             with six.assertRaisesRegex(self, Exception, "Oops"):
                 with transaction.atomic(savepoint=False):
                     Reporter.objects.create(first_name="Calculus")
                     raise Exception("Oops, that's his last name")
             # The third insert couldn't be roll back. Temporarily mark the
             # connection as not needing rollback to check it.
             self.assertTrue(transaction.get_rollback())
             transaction.set_rollback(False)
             self.assertEqual(Reporter.objects.count(), 3)
             transaction.set_rollback(True)
         # The second insert couldn't be roll back. Temporarily mark the
         # connection as not needing rollback to check it.
         self.assertTrue(transaction.get_rollback())
         transaction.set_rollback(False)
         self.assertEqual(Reporter.objects.count(), 3)
         transaction.set_rollback(True)
     # The first block has a savepoint and must roll back.
     self.assertQuerysetEqual(Reporter.objects.all(), [])
Exemplo n.º 24
0
    def test_mark_for_rollback_on_error_in_transaction(self):
        with transaction.atomic(savepoint=False):

            # Swallow the intentional error raised.
            with self.assertRaisesMessage(Exception, "Oops"):

                # Wrap in `mark_for_rollback_on_error` to check if the transaction is marked broken.
                with transaction.mark_for_rollback_on_error():

                    # Ensure that we are still in a good state.
                    self.assertFalse(transaction.get_rollback())

                    raise Exception("Oops")

                # Ensure that `mark_for_rollback_on_error` marked the transaction as broken …
                self.assertTrue(transaction.get_rollback())

            # … and further queries fail.
            msg = "You can't execute queries until the end of the 'atomic' block."
            with self.assertRaisesMessage(transaction.TransactionManagementError, msg):
                Reporter.objects.create()

        # Transaction errors are reset at the end of an transaction, so this should just work.
        Reporter.objects.create()
 def test_api_exception_rollback_transaction(self):
     """
     Transaction is rollbacked by our transaction atomic block.
     """
     request = factory.post("/")
     num_queries = 4 if getattr(connection.features, "can_release_savepoints", False) else 3
     with self.assertNumQueries(num_queries):
         # 1 - begin savepoint
         # 2 - insert
         # 3 - rollback savepoint
         # 4 - release savepoint (django>=1.8 only)
         with transaction.atomic():
             response = self.view(request)
             self.assertTrue(transaction.get_rollback())
     self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
     assert BasicModel.objects.count() == 0
 def test_api_exception_rollback_transaction(self):
     """
     Transaction is rollbacked by our transaction atomic block.
     """
     request = factory.post('/')
     num_queries = 4 if connection.features.can_release_savepoints else 3
     with self.assertNumQueries(num_queries):
         # 1 - begin savepoint
         # 2 - insert
         # 3 - rollback savepoint
         # 4 - release savepoint
         with transaction.atomic():
             response = self.view(request)
             assert transaction.get_rollback()
     assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
     assert BasicModel.objects.count() == 0
Exemplo n.º 27
0
    def test_generic_exception_delegate_transaction_management(self):
        """
        Transaction is eventually managed by outer-most transaction atomic
        block. DRF do not try to interfere here.

        We let django deal with the transaction when it will catch the Exception.
        """
        request = factory.post('/')
        with self.assertNumQueries(3):
            # 1 - begin savepoint
            # 2 - insert
            # 3 - release savepoint
            with transaction.atomic():
                self.assertRaises(Exception, self.view, request)
                assert not transaction.get_rollback()
        assert BasicModel.objects.count() == 1
    def test_generic_exception_delegate_transaction_management(self):
        """
        Transaction is eventually managed by outer-most transaction atomic
        block. DRF do not try to interfere here.

        We let django deal with the transaction when it will catch the Exception.
        """
        request = factory.post("/")
        with self.assertNumQueries(3):
            # 1 - begin savepoint
            # 2 - insert
            # 3 - release savepoint
            with transaction.atomic():
                self.assertRaises(Exception, self.view, request)
                self.assertFalse(transaction.get_rollback())
        assert BasicModel.objects.count() == 1
Exemplo n.º 29
0
 def test_api_exception_rollback_transaction(self):
     """
     Transaction is rollbacked by our transaction atomic block.
     """
     request = factory.post('/')
     num_queries = (4 if getattr(connection.features,
                                 'can_release_savepoints', False) else 3)
     with self.assertNumQueries(num_queries):
         # 1 - begin savepoint
         # 2 - insert
         # 3 - rollback savepoint
         # 4 - release savepoint (django>=1.8 only)
         with transaction.atomic():
             response = self.view(request)
             assert transaction.get_rollback()
     assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
     assert BasicModel.objects.count() == 0
Exemplo n.º 30
0
    def test_force_rollback(self):
        with transaction.atomic():
            Reporter.objects.create(first_name="Tintin")
            # atomic block shouldn't rollback, but force it.
            self.assertFalse(transaction.get_rollback())
            transaction.set_rollback(True)
        self.assertQuerysetEqual(Reporter.objects.all(), [])
        self.assertAtomicSignalCalls(
            # Enter atomic transaction block.
            enter_block_atomic_signal_call_sequence(True) +

            # Create Reporter.
            create_model_atomic_signal_call_sequence() +

            # Leave atomic transaction with forced rollback.
            leave_block_atomic_signal_call_sequence(True, False)
        )
Exemplo n.º 31
0
def _ctit_db_wrapper(trans_safe=False):
    """
    Wrapper to avoid undesired actions by Django ORM when managing settings
    if only getting a setting, can use trans_safe=True, which will avoid
    throwing errors if the prior context was a broken transaction.
    Any database errors will be logged, but exception will be suppressed.
    """
    rollback_set = None
    is_atomic = None
    try:
        if trans_safe:
            is_atomic = connection.in_atomic_block
            if is_atomic:
                rollback_set = transaction.get_rollback()
                if rollback_set:
                    logger.debug(
                        'Obtaining database settings in spite of broken transaction.'
                    )
                    transaction.set_rollback(False)
        yield
    except DBError as exc:
        if trans_safe:
            level = logger.warning
            if isinstance(exc, ProgrammingError):
                if 'relation' in str(exc) and 'does not exist' in str(exc):
                    # this generally means we can't fetch Tower configuration
                    # because the database hasn't actually finished migrating yet;
                    # this is usually a sign that a service in a container (such as ws_broadcast)
                    # has come up *before* the database has finished migrating, and
                    # especially that the conf.settings table doesn't exist yet
                    level = logger.debug
            level(
                f'Database settings are not available, using defaults. error: {str(exc)}'
            )
        else:
            logger.exception(
                'Error modifying something related to database settings.')
    finally:
        if trans_safe and is_atomic and rollback_set:
            transaction.set_rollback(rollback_set)
Exemplo n.º 32
0
def view(request):
    data = {}
    if request.method == 'POST':
        if 'user' in request.session:
            if 'action' in request.POST:
                action = request.POST['action']
                if action == 'add_factura':
                    try:
                        vali = FacturaForm(request.POST)
                        if vali.is_valid():
                            factura = Factura(
                                ruccliente=vali.cleaned_data['ruccliente'],
                                nombrecliente=vali.
                                cleaned_data['nombrecliente'])
                            factura.save()
                            datos = json.loads(request.POST['lista_items1'])
                            for p in datos:
                                det = FacturaProducto(factura=factura,
                                                      producto=p['producto'],
                                                      precio=p['precio'],
                                                      cantidad=p['cantidad'])
                                det.save()
                            return JsonResponse({"result": "ok"})
                        else:
                            return JsonResponse({
                                "result":
                                "error",
                                "mensaje":
                                'datos erroneos en el formulario.'
                            })
                    except Exception as ex:
                        transaction.get_rollback()
                        return JsonResponse({
                            "result":
                            "error",
                            "mensaje":
                            'Ocurrio un problema contacte con el administrador.'
                        })

        else:
            return JsonResponse({"result": "session"})
            # return HttpResponseRedirect("/")
    else:
        if 'action' in request.GET:
            action = request.GET['action']
            if action == 'add_factura':
                data['title'] = u'Agregar Factura'
                data['form'] = FacturaForm()
                return render(request, "factura/add_factura.html", data)

            if action == 'edit_pais':
                data['title'] = u'Editar Pais'
                data['pais'] = pais = Pais.objects.get(
                    pk=int(request.GET['id']))
                data['form'] = PaisForm(initial={
                    'nombre': pais.nombre,
                    'estado': pais.estado
                })
                return render(request, "add_pais.html", data)
        else:
            data['user'] = request.session['user']
            data['factura'] = Factura.objects.all()
            return render(request, "factura.html", data)