<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Stefano Apostolico's Blog</title><link href="http://stefanoapostolico.com/" rel="alternate"></link><link href="http://stefanoapostolico.com/feeds/all.atom.xml" rel="self"></link><id>http://stefanoapostolico.com/</id><updated>2017-10-10T00:00:00+02:00</updated><entry><title>Using multiple serializers with DjangoRestFramework</title><link href="http://stefanoapostolico.com/2017/10/10/drf-multiple-serializers.html" rel="alternate"></link><published>2017-10-10T00:00:00+02:00</published><updated>2017-10-10T00:00:00+02:00</updated><author><name>Stefano Apostolico</name></author><id>tag:stefanoapostolico.com,2017-10-10:/2017/10/10/drf-multiple-serializers.html</id><summary type="html">&lt;p&gt;How to use different serializers with DjangoRestFramework&lt;/p&gt;
</summary><content type="html">&lt;p&gt;How to use different serializers with DjangoRestFramework&lt;/p&gt;

&lt;p&gt;Imagine to have a viewset and you want to parametrize the output,
using different serializers.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;Person&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;Model&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
    &lt;span class="nv"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;CharField&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;CharField&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;CharField&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;EmailField&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;CharField&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;birthday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;models&lt;/span&gt;.&lt;span class="nv"&gt;DateField&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;

&lt;span class="nv"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;PersonSerializer&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;HouseSerializer&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:    
    &lt;span class="nv"&gt;full_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;serializers&lt;/span&gt;.&lt;span class="nv"&gt;SerializerMethodField&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;

    &lt;span class="nv"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;Meta&lt;/span&gt;:
        &lt;span class="nv"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;House&lt;/span&gt;
        &lt;span class="nv"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;last_name&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;first_name&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mail&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;full_name&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;get_full_name&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;self&lt;/span&gt;, &lt;span class="nv"&gt;obj&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{0.last_name}, {1.first_name}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;.&lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;obj&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;PersonView&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;DynamicSerializerMixin&lt;/span&gt;, &lt;span class="nv"&gt;generics&lt;/span&gt;.&lt;span class="nv"&gt;ListAPIView&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
    &lt;span class="nv"&gt;queryset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;House&lt;/span&gt;.&lt;span class="nv"&gt;objects&lt;/span&gt;.&lt;span class="nv"&gt;all&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
    &lt;span class="nv"&gt;serializer_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;HouseSerializer&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;it is easy to build a "serializer factory" to build on the fly &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; {}

&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;serializer_factory&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;model&lt;/span&gt;, &lt;span class="nv"&gt;base&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;ModelSerializer&lt;/span&gt;, &lt;span class="nv"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;None&lt;/span&gt;, &lt;span class="nv"&gt;exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;None&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
    &lt;span class="nv"&gt;attrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; {&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;: &lt;span class="nv"&gt;model&lt;/span&gt;}
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;fields&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;None&lt;/span&gt;:
        &lt;span class="nv"&gt;attrs&lt;/span&gt;[&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fields&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;] &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;fields&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;exclude&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;None&lt;/span&gt;:
        &lt;span class="nv"&gt;attrs&lt;/span&gt;[&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;exclude&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;] &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;exclude&lt;/span&gt;

    &lt;span class="nv"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;object&lt;/span&gt;,&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;hasattr&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;base&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Meta&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
        &lt;span class="nv"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;base&lt;/span&gt;.&lt;span class="nv"&gt;Meta&lt;/span&gt;, &lt;span class="nv"&gt;object&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;Meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Meta&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;parent&lt;/span&gt;, &lt;span class="nv"&gt;attrs&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt;:
        &lt;span class="nv"&gt;class_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt;.&lt;span class="nv"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Serializer&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;:
        &lt;span class="nv"&gt;class_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Serializer&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;base&lt;/span&gt;&lt;span class="ss"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;class_name&lt;/span&gt;, &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;base&lt;/span&gt;,&lt;span class="ss"&gt;)&lt;/span&gt;, {&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Meta&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;: &lt;span class="nv"&gt;Meta&lt;/span&gt;, }&lt;span class="ss"&gt;)&lt;/span&gt;


&lt;span class="nv"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;DynamicSerializerMixin&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;object&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
    &lt;span class="nv"&gt;serializers_fieldsets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; {&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;std&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;: &lt;span class="nv"&gt;None&lt;/span&gt;}
    &lt;span class="nv"&gt;serializer_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;ModelSerializer&lt;/span&gt;

    &lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;get_serializer_class&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;self&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
        &lt;span class="nv"&gt;ser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;self&lt;/span&gt;.&lt;span class="nv"&gt;request&lt;/span&gt;.&lt;span class="nv"&gt;QUERY_PARAMS&lt;/span&gt;.&lt;span class="nv"&gt;get&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;serializer&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;std&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;ser&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;cache&lt;/span&gt;:                
            &lt;span class="nv"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;self&lt;/span&gt;.&lt;span class="nv"&gt;serializers_fieldsets&lt;/span&gt;.&lt;span class="nv"&gt;get&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ser&lt;/span&gt;, &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;std&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;cache&lt;/span&gt;[&lt;span class="nv"&gt;ser&lt;/span&gt;] &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nv"&gt;serializer_factory&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;self&lt;/span&gt;.&lt;span class="nv"&gt;model&lt;/span&gt;,
                                  &lt;span class="nv"&gt;self&lt;/span&gt;.&lt;span class="nv"&gt;serializer_class&lt;/span&gt;,
                                  &lt;span class="nv"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;fields&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;cache&lt;/span&gt;[&lt;span class="nv"&gt;ser&lt;/span&gt;]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;adopt it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;PersonView&lt;/span&gt;(&lt;span class="n"&gt;DynamicSerializerMixin&lt;/span&gt;, &lt;span class="n"&gt;generics&lt;/span&gt;.&lt;span class="n"&gt;ListAPIView&lt;/span&gt;):
    &lt;span class="n"&gt;queryset&lt;/span&gt; = &lt;span class="n"&gt;Person&lt;/span&gt;.&lt;span class="n"&gt;objects&lt;/span&gt;.&lt;span class="nb"&gt;all&lt;/span&gt;()
    &lt;span class="n"&gt;serializer_class&lt;/span&gt; = &lt;span class="n"&gt;PersonSerializer&lt;/span&gt;
    &lt;span class="n"&gt;serializers_fieldsets&lt;/span&gt; = {&lt;span class="s"&gt;'std'&lt;/span&gt;: &lt;span class="n"&gt;PersonSerializer&lt;/span&gt;,
                             &lt;span class="s"&gt;'simple'&lt;/span&gt;: (&lt;span class="s"&gt;'first_name'&lt;/span&gt;, &lt;span class="s"&gt;'last_name'&lt;/span&gt;)
                             }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;invoke it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;serializer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;
&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;serializer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;simpleA&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="django"></category><category term="drf"></category><category term="django-rest-framework"></category></entry><entry><title>py.test and Django</title><link href="http://stefanoapostolico.com/2016/11/10/pytest_webtest_django.html" rel="alternate"></link><published>2016-11-10T00:00:00+01:00</published><updated>2016-11-10T00:00:00+01:00</updated><author><name>Stefano Apostolico</name></author><id>tag:stefanoapostolico.com,2016-11-10:/2016/11/10/pytest_webtest_django.html</id><summary type="html">&lt;p&gt;Test django application with py.test and WebTest&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Test django application with py.test and WebTest&lt;/p&gt;

&lt;p&gt;I quit using default Django test suite some years ago, sometimes I go back to it to see if something new can change my mind, but up to now I continue to prefer my choice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pytest.org/latest/"&gt;py.test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://webtest.pythonpaste.org/en/latest/index.html"&gt;WebTest&lt;/a&gt; with &lt;a href="http://pypi.python.org/pypi/django-webtest"&gt;django-webtest&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;Several reasons - here's a few:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It can run unittest, doctest, and nose, style tests suites, making it ideal for new and legacy projects.&lt;/li&gt;
&lt;li&gt;It includes an intuitively named raises context manager for testing exceptions.&lt;/li&gt;
&lt;li&gt;You can define fixture arguments to generate baseline data. This is very, very different from Django-style fixtures.&lt;/li&gt;
&lt;li&gt;Via &lt;code&gt;pytest.ini/setup.cfg&lt;/code&gt; you can change the behavior of pytest.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrates nicely with setup.py.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WebTest allows you to model a user's experience much more closely as it is smart about mark-up. Instead of hand-crafting GET and POST requests, you can use the WebTest API to follow links and submit forms - this is what users actually do. As a result, your tests accurately capture user stories.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Writing functional tests with WebTest is both easier and quicker than using Django's test client. It's much simpler to fill in forms that construct complicated arrays of POST data - this is particularly noticable with formsets.&lt;/li&gt;
&lt;li&gt;The WebTest response object supports several ways of parsing the response HTML, making it easy to make complicated assertions about the response.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;response.showbrowser()&lt;/code&gt; is simply amazing&lt;/li&gt;
&lt;/ul&gt;</content><category term="django"></category><category term="pytest"></category></entry><entry><title>False Myths: Customers does not care about technology they care about money</title><link href="http://stefanoapostolico.com/2016/10/26/technology_vs_money.html" rel="alternate"></link><published>2016-10-26T00:00:00+02:00</published><updated>2016-10-26T00:00:00+02:00</updated><author><name>Stefano Apostolico</name></author><id>tag:stefanoapostolico.com,2016-10-26:/2016/10/26/technology_vs_money.html</id><summary type="html"></summary><content type="html">
&lt;p&gt;Yesterday a sentence like this was posted in a collaboration platform:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"At the end of the day your customers don’t care whether you’re agile, 
lean or practice design thinking."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I fully agree with the essence of this idea, but it does sounds misleading in one aspect of presentation: This sentence, when interpreted as "customers only care about money", could be a huge mistake. &lt;/p&gt;
&lt;p&gt;Just because our customers do not care how we work, it does not mean that we should not care about methodologies and process.
I don't care what products and tools my dentist uses; it's upto him, but I expect he cares about them a lot!
Tools, processes and metodologies are in our domain and scope - though they do not need to be endorsed by or exposed to our customers,
without an internal professional approach, we cannot deliver great products and services that solve meaningful problems for them in effective ways.&lt;/p&gt;
&lt;p&gt;When the Business/Customer allocates a budget, there's an expectation of return value: a working, reliable product delivered in time and within budget.
If something goes wrong, the Business/Customer complains about money because it is the only "unit of measure" that he/she knows that is understandable in our domain, and is the only common language he/she can speak with us. &lt;/p&gt;
&lt;p&gt;As an analogy, When a new-bought car breaks down after a week, we go back to the vendor and complain &lt;/p&gt;
&lt;p&gt;&lt;em&gt;"Hey, I paid $$$ for this car but it does not work anymore!"&lt;/em&gt;, &lt;/p&gt;
&lt;p&gt;only because we do not know how to say &lt;/p&gt;
&lt;p&gt;&lt;em&gt;"Hey, this car has a design error &lt;xyz&gt;, you should not have sold it!"&lt;/xyz&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Ultimately, businesses care about "good products", but the way to deliver 
them cannot pass through a wrong approach or ignoring any methodology only because 
businesses don't care about them "explicitly". &lt;/p&gt;
&lt;p&gt;Again, as an analogy from our experience on flights, I don't think we would expect our planes to be driven overlooking the current best practices, procedures and commonsense, or, even worst, piloted by the first available person.&lt;/p&gt;
&lt;p&gt;Skills, knowledge  and mastering the domain is the only way to give to the 
Business what it expects, any another approach is only a workaroud that 
undermines our reputation and credibility day after day.&lt;/p&gt;</content><category term="methodology"></category><category term="myths"></category></entry><entry><title>django and pdbpp</title><link href="http://stefanoapostolico.com/2015/10/26/django_pdbpp.html" rel="alternate"></link><published>2015-10-26T00:00:00+01:00</published><updated>2015-10-26T00:00:00+01:00</updated><author><name>Stefano Apostolico</name></author><id>tag:stefanoapostolico.com,2015-10-26:/2015/10/26/django_pdbpp.html</id><summary type="html">&lt;p&gt;Quick tips how to enable pdb with django&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Quick tips how to enable pdb with django&lt;/p&gt;

&lt;p&gt;&lt;a class="reference external" href="https://bitbucket.org/antocuni/pdb/src"&gt;pdbpp&lt;/a&gt; is my favourite debugger, I use integrated IDE for my development, but I still
prefer use the command line for most of my daily work.
I find Django sometimes cryptic when some error occurs, (ie. data migrations) this
simple hack, enables pdb when I need, without install third party packages.&lt;/p&gt;
&lt;p&gt;It is possible run &lt;cite&gt;python -m pdb manage.py &amp;lt;command&amp;gt;&lt;/cite&gt; but this has, sometimes,
some strange side effects, like continue prompting for restarting,
and I loose autocompletion feature (I know, I'm lazy).&lt;/p&gt;
&lt;p&gt;In the end I rolled out this custom &lt;cite&gt;manage.py&lt;/cite&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DJANGO_SETTINGS_MODULE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wfp_commonapi.settings._&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'USER'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.management&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;execute_from_command_line&lt;/span&gt;

    &lt;span class="n"&gt;debug_on_error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'--pdb'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'--pdb'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;execute_from_command_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;debug_on_error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;traceback&lt;/span&gt;
            &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exc_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;traceback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print_exc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post_mortem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;now I can&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;migrate&lt;/span&gt; &lt;span class="n"&gt;app1&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and we'll enter in the pdb screen if an error occurs&lt;/p&gt;
</content><category term="django"></category><category term="pdb"></category></entry><entry><title>cx-Oracle 5.2 on OSX (El Capitan)</title><link href="http://stefanoapostolico.com/2015/10/14/install_cxoracle_52_on_osx.html" rel="alternate"></link><published>2015-10-14T00:00:00+02:00</published><updated>2015-10-14T00:00:00+02:00</updated><author><name>Stefano Apostolico</name></author><id>tag:stefanoapostolico.com,2015-10-14:/2015/10/14/install_cxoracle_52_on_osx.html</id><summary type="html">&lt;p&gt;Install cx-Oracle 5.2 on OSX (El Capitan), mostly for my reference&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Install cx-Oracle 5.2 on OSX (El Capitan), mostly for my reference&lt;/p&gt;

&lt;div class="section" id="what-we-install"&gt;
&lt;h2&gt;What we install&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Oracle Instant Client 64bit 11.2.0.4.0&lt;/li&gt;
&lt;li&gt;cx-Oracle 5.2&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/data/oracle/instantclient_11_2
mkdir -p &lt;span class="nv"&gt;$ORACLE_HONE&lt;/span&gt;

&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;DYLD_LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;

unzip &lt;span class="s1"&gt;'instantclient*.zip'&lt;/span&gt; -d &lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;/..

ln -s &lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;/libclntsh.dylib.11.1 &lt;span class="nv"&gt;$ORACLE_HOME&lt;/span&gt;/libclntsh.dylib
pip install cx-Oracle
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="links"&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html"&gt;Oracle Instant Client Downloads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="cx_Oracle"></category><category term="SIP"></category></entry></feed>