Sunday, July 5, 2009

django-sorting a generic way of queryset sorting


Just found a great project django-sorting. It's a generic way of queryset sorting.
It's based on middleware, and templatetag.

Please read the README.txt of the project.

In couple easy steps you get sorting:

1. Download & install django-sorting
2.In your settings.py
- add 'django-sorting' to INSTALLED_APPS
- add 'django_sorting.middleware.SortingMiddleware' to MIDDLEWARE_CLASSES
(make sure 'django.core.context_processors.request' is in your TEMPLATE_CONTEXT_PROCESSORS
3. In your template code: (the one below goes directly from README.txt

...
{% anchor first_name "First Name" %}
{% anchor last_name "Last Name" %}
{% anchor creation_date Creation flojax my_container %}
...

The first argument is a field of the objects list, and the second

one(optional) is a title that would be displayed. The previous

snippet will be rendered like this:


...
First Name
Last Name
Creation
...



It's BRILLIANT!


You should also use django-pagination for pagination support written by Eric as well.


Thank you ERIC!

Ps. Big thanks go to Karim (first author of django-sorting code) and other contributtors of these 2 great projects.

Monday, January 26, 2009

[PL] Authinfo i transfer domeny

Postanowiłem przenieść swoje domeny *.pl do innego registrara.

Jak wszyscy wiemy, niedawno NASK obniżył opłaty za przedłużenie domen,
która w przypadku domen *.pl wynosi 40 PLN netto. Obniżka cen miała miejsce niedawno.
Mowa o obniżce cen dla partnerów. Zwykły zjadacz domen dalej płaci 200 PLN netto, a raczej 244 pln brutto.

Jak można się domyśleć, nie przełożyło się to na obniżki cen domen u popularnych u nas firm rejestrujących domeny, jak home.pl itd - cena 99 pln netto (stan na 26.01.2009).

Wiadomo, każdy chce zarabiać.

Wcześniej transferowałem domenę *.com z firmy godaddy. Tam w 10 sekund, po wybraniu opcji "wyślij kod authinfo" otrzymałem emailem kod. Proste i przyjemne.

Niestety nie w Polsce.
Pierw wypełnienie formularza, wpisanie telefonu i powodu, dla którego chcemy authinfo. Można się domyśleć - bo chcę dokonać transferu (nie kłamałem, wpisałem).

Otrzymałem po 2 dniach emaila, z propozycją obniżenia opłaty za przedłużenie ze 100 do 80 pln netto. W emailu załączony był również wniosek. Wypełniłem, podpieczętowałem, przefaxowałem.

Następnie dostałem emailem info, że wniosek przyjęty i że mam zalogować się znowu do innej strony (podano mi login/hasło). Tam się zalogowałem i znowu kolejne 2 wnioski do wypełniania, podpisania, podpieczętowania i przefaxowania wraz dokumentami: NIP, regon, wpis do ewidencji.

Uwaga: wniosek dotyczy tylko jednej z dwóch domen *.pl
Do jednej dostałem już kod authinfo! Widocznie chcą mocnych dowodów, że ja to ja.

Szkoda tylko papieru, drzew. Zarabia na tym chociaż operator telekomunikacyjny,
bo faxy wysyłać trzeba.

Tuesday, January 13, 2009

Ćwicz po pracy!

Uważam, że człowiek może dostać kręćka od monotonnego trybu życia, w skład którego wchodziłyby tylko praca i sen.

Zachęcam każdego gorąco do aktywności ruchowej minimum 2 razy w tygodniu.
Gorąco polecam basen, piłkę nożną oraz sztuki walki :)

Dla mieszkających w okolicy Gdyni polecić mogę gdyńską szkołę TaiChi, oraz KungFu (a także Qigong) - YMAA GDYNIA.

Treningi odbywają się w poniedziałki oraz środy.
W pozostałe dni polecam basen :)

Thursday, October 16, 2008

SAY NO TO FLASH POPUPS!

I've been a Firefox user for a long time.

After Google Chrome has been published I decided to check it out.
After 1 day I had to switch back to Firefox.

The reason?
https://addons.mozilla.org/firefox/addon/10 (Firefox AdBlock plugin)

It's IMPOSSIBLE to watch the web without this plugin.
Flash plugins everywhere ... This is horrible.

People! Use this plugin, do not let manipulate and waste your time on
pages using this harmful type of advertising.

Boycote it! Let others know to not use it!
Admins, block ad hosts too!

I do not mean to fight with ads. I can watch ads, as long as it does not eat 100% of my CPU and some fuckin* flash poup appears! AARGH!!

THIS IS CRAZY!

Thursday, October 9, 2008

django-tables generic way for displaying tables (pagination included)

In thnis short post I would like to let you know about the great project
django-tables.

You can read more about it at:
http://blog.elsdoerfer.name/2008/07/09/django-tables-a-queryset-renderer/

In a couple of words it lets you:
- display the table using one template which lets you sort & paginate easily (filtering in plans!)

By reading the text below you will find out how to create table with sort & pagination quickly.

In usage it's very similar do django newforms (forms as of 1.0)
Example: (views.py)

class MyTable(tables.ModelTable):

  class Meta:
      model = SomeModel

def view_something(request):
  table = MyTable(queryset, order_by=request.GET.get('sort','some_field))

  return render_to_response('templates/table.html', {'table': table, 'rows' : table.rows})
# we need to return table, and  rows separately to use django-pagination (though django-tables provides its own pagination mechanism)

Now let's get to template:

{% load pagination_tags %}
{% autopaginate rows 10 %}



  {% for column in table.columns %}

  {% endfor %}


{% for row in rows %}

  {% for value in row %}

{% endfor %}


{% if column.sortable %}
{{ column }}
{% if column.is_ordered_reverse %}

{% else %}

{% endif %}
{% else %}
{{ column }}
{% endif %}
{{ value }}
{% endfor %}
{% paginate %}


That's it!

This way you get generic way of displaying tables + sorting ability.
By default, django-tables takes field names for table headers when using ModelTable (verbose_name is in plans as well).
You can exclude displaying fields too!

As for now, you can specify your own names in MyTable class.

Let's get back to our class:

class MyTable(tables.ModelTable):
  class Meta:
      model = SomeModel

  field1 = tables.Column(name="Name")
  field_we_want_to_exclude = tables.Column(visiable=Fale, sortable=False)


NOTE:
Django tables is also aware of ForeignKey relations.

Check it out!

Monday, March 3, 2008

Django ModelForm - replacement for form_for_model & form_for_instance

Each commit, Django gets more amazing.

I wrote about newforms library before. The library was a big step in Django form displaying and validating.

The first approach was to use forms.form_for_model() and forms.form_for_instance() respectively.

As Django programmer I found this a little confusing. Both were similar. The only difference was that form_for_instance() took an object instance for saving instead
of creating a new one. Recently django developers came up with a great idea - forms.ModelForm which combines both into one. It's great!

Just take a look at the example below.
Assume you want to create a new view function for creating & editing an object.
You only want to edit 3 fields (name, last_name, status). Also, you've created a
customized field type for "status", and want to use that.

Scenario #1: (forms.form_for_model && forms.form_for_instance)


def f_callback(field, **kwargs):
if field.name == "status":
return MyStatusField(**kwargs)
else:
return field.formfield(**kwargs)

def create_edit_customer(request, customer_id=None):

# check if object_id is None and if object exists
if object_id is None:
CustomerForm = forms.form_for_model(Customer,
formfield_callback=f_callback,
fields=('name','last_name','status')
else:
customer = get_object_or_404(Customer, id=customer_id)
CustomerForm = forms.form_for_instance(customer,
formfield_callback=f_callback,
fields=('name','last_name','status')

if request.method == "POST":
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('customer/added/')
else:
form = CustomerForm()

return render_to_response("customers/customer_form.html", {'form' : form })




You could create your own form_for_model & form_for_instance subclass (using forms.BaseForm for example), but it would be too complicated. Hope you don't use this form often :-)

Scenario #2 (ModelForm)

1. Longer version.


class CustomerModelForm(forms.ModelForm):

class Meta:
model = Customer
fields = ('name','last_name','status')

status = MyCustomerField()

def create_edit_customer(request, customer_id=None):

if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None


if request.method == "POST":
form = CustomerModelForm(data=request.POST, instance=customer)
if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")
else:
form = CustomerModelForm(instance=customer)

return render_to_response("customers/customer_form.html", {'form' : form })



2. Shorter version.


class CustomerModelForm(forms.ModelForm):

class Meta:
model = Customer
fields = ('name','last_name','status')

status = MyCustomerField()

def create_edit_customer(request, customer_id=None):

if customer_id is not None:
customer = get_object_or_404(Customer, id=customer_id)
else:
customer = None

form = CustomerModelForm(data=request.POST or None, instance=customer)

if form.is_valid():
form.save()
return HttpResponseRedirect("/customer/added/")

return render_to_response("customers/customer_form.html", {'form' : form }



We are using one form class for editing & creating objects.
We can also subclass CustomerModelForm and edit/change the way the form looks
and behave (by adding field clean() method.

Django forms library looks better each day :-)

Sunday, March 2, 2008

Vote for Gdynia in Monopoly Game

I was born in Gdynia, I grew up in Gdynia.. and I am happy to live in Gdynia.

Now it's chance for anybody to vote for Gdynia in the Worldwide Monopoly
city competition.

Log in at:
http://www.monopolyworldvote.com/pl_PL/world and vote.
You can give your vote once a day.

Thanks!

---
Urodziłem się w Gdyni, dorastałem w Gdyni i nadal mieszkam w Gdyni.
To cudowne miasto ma teraz niepowtarzalną okazję zaistnieć w
ogólnoświatowej wersji gry Monopol, w którą grają miliony
ludzi na świecie.
To niepowtarzalna szansa dla promocji naszego miasta, ale też i kraju,
czy też rejonu.

Oddaj swój głos na stronie:
http://www.monopolyworldvote.com/pl_PL/world

Możesz głosować codziennie 1 raz!

Dzięki !