Z pew­no­ścią naczy­ta­łeś się już, jakie to Satchmo nie jest dosko­nałe, zazdro­ścisz i chciał­byś stwo­rzyć coś rów­nie wspa­nia­łego. Dość jed­nak nie­prze­spa­nych nocy, albo­wiem przy­go­to­wa­łem krótki porad­nik, który w kilku kro­kach pozwoli ci dorów­nać mistrzom.

Sięgaj tam, gdzie import nie sięga

Tak jest, zacznij od stwo­rze­nia modułu z myśl­ni­kiem w nazwie. Nie­stety, oczy­wi­sta nazwa email-auth.py została już zajęta — musisz się bar­dziej wysi­lić. Zna­jo­mym oczy wypadną z zazdro­ści, gdy tylko pierw­szy raz zobaczą:

hahaha = __import__('pokonalem-was', globals(), locals(), [], -1)

Uatrakcyjniaj pętle

Od dawna wia­domo już, że przed­wcze­sna opty­ma­li­za­cja jest złem, naszą odpo­wie­dzią będzie zatem przed­wcze­sna dez­op­ty­ma­li­za­cja! Oto przy­kład atrak­cyj­nego wyświe­tle­nia listy:

{% for product in products %}
    {% if forloop.first %} <ul>  {% endif %}
        <li>{% thumbnail product.main_image.picture 85x85 as image %}
        <a href="{{ product.get_absolute_url }}"><img src="{{ image }}" width="{{ image.width }}" height="{{ image.height }}" /></a>
        <a href="{{ product.get_absolute_url }}">{{ product.translated_name }}</a></li>
    {% if forloop.last %} </ul> {% endif %}
{% endfor %}

Tylko wyobraź sobie ich miny! Jeśli chcesz prze­sko­czyć mistrza, spró­buj prze­nieść kod do Pythona:

for counter, product in enumerate(products):
    if counter == 0:
        print '<ul>'
    # ...i tak dalej

Nie daj się zaszufladkować

Nie łudźmy się — prze­strze­nie nazw są dla fra­je­rów. Bez cere­gieli pakuj wszystko w ścieżkę Pythona i upew­nij się, że tak wła­śnie impor­tu­jesz swoje moduły. Pokaż, że jesteś waż­nia­kiem i twórz moduły o jak naj­ogól­niej­szych nazwach. Naucz fajan­sów pokory, tych kilka dodat­ko­wych wpi­sów w PYTHONPATH ich nie zabije. Mogą to zro­bić kon­flikty, ale jeśli chcą uży­wać cze­goś ponad twój fra­me­work, to sami są sobie winni i zasłu­żyli na karę.

export PYTHONPATH=~/web/satchmo/satchmo/apps

Unikaj biurokracji

Po co męczyć się z for­mu­la­rzami, gdy do wszyst­kiego się­gnąć można już w widoku? Nie­zwy­kle istotne jest tu uni­ka­nie request.REQUEST.

if request.method=="POST":
    reqdata = request.POST
else:
    reqdata = request.GET

if reqdata.has_key('quantity'):
    try:
        quantity = round_decimal(reqdata['quantity'], places=2, roundfactor=.25)
    except RoundedDecimalError:
        quantity = Decimal('1.0')
        log.warn("Could not parse a decimal from '%s', returning '1.0'", reqdata['quantity'])
else:
    quantity = Decimal('1.0')

Jeśli już musisz użyć for­mu­la­rza, upew­nij się, że upa­ku­jesz wszyst­kie, nie­zwią­zane ze sobą grupy pól w jed­nej dużej kla­sie. Dzięki temu zaosz­czę­dzisz sobie kilka wywo­łań is_valid() i jed­no­cze­śnie uda­rem­nisz wszel­kie próby innego wyko­rzy­sta­nia poszcze­gól­nych czę­ści przez te nie­do­ro­zwoje, które mają czel­ność impor­to­wać twoje klasy.

Wyznaczaj nowe trendy

Przez takich jak oni, pro­gra­mo­wa­nie obiek­towe stoi prak­tycz­nie w miej­scu. Pokaż im nowe sztuczki, takie jak zastą­pie­nie roz­sze­rza­nia klas nad­pi­sy­wa­niem funk­cji w locie¹:

def confirm_info(request, template='shop/checkout/protx/confirm.html', extra_context={}):
    payment_module = config_get_group('PAYMENT_PROTX')
    controller = confirm.ConfirmController(request, payment_module)
    controller.templates['CONFIRM'] = template
    controller.extra_context = extra_context
    controller.onForm = secure3d_form_handler
    controller.confirm()
    return controller.response

¹ W rze­czy­wi­sto­ści ConfirmController.onForm jest w kon­struk­to­rze klasy usta­wiany na ConfirmController._onForm, co można uznać za archi­tek­turę po dwa­kroć lepszą.

Parametry dobieraj z rozmachem

Piękno tkwi w róż­no­rod­no­ści. Upew­nij się zatem, że wyczer­piesz wszel­kie metody osią­gnię­cia tego samego celu.

class ProductImage(models.Model):
    # ...
    picture = ImageWithThumbnailField(verbose_name=_('Picture'),
        upload_to="__DYNAMIC__",
        name_field="_filename",
        max_length=200)
    # ...

class ImageWithThumbnailField(ImageField):
    # ...
    def __init__(self, verbose_name=None, name=None,
                 width_field=None, height_field=None,
                 auto_rename=NOTSET, name_field=None,
                 upload_to=upload_dir, **kwargs):
        # ...
        if upload_to == "__DYNAMIC__":
            upload_to = upload_dir
        # ...

Bądź elastyczny

Teraz twój sklep znaj­duje się w Pol­sce, ale kto wie, co będzie po obie­dzie? Upew­nij się, że cała kon­fi­gu­ra­cja może być edy­to­wana w locie. Zwłasz­cza te jej frag­menty, które wyma­gają restartu apli­ka­cji. To jedna z wielu sztu­czek, które zapew­nią ci popu­lar­ność w branży. Co prawda dawni przy­ja­ciele zazdrosz­czą ci już do tego stop­nia, że prze­stali się do cie­bie odzy­wać, ale i tak nie tęsk­nisz po tych pro­sta­kach. Od teraz twoim jedy­nym przy­ja­cie­lem jest apli­ka­cja django-livesettings. Na innych nie masz szans, bo przy­ja­ciół poznaje się w bie­dzie, a ty prze­cież wła­śnie zyska­łeś umie­jęt­no­ści, dzięki któ­rym prak­tycz­nie już jesteś bogaty.