Django: реалізація динамічного select'у

Не доводилось раніше використовувати динамічний select, тобто select, який через ajax підтягує значення відповідно до значення вибраного в попередньому select'і. Тож довелось розібратись. Пропоную свій код, який не претендує на супер-оригінальність


models.py

# -*- coding:utf-8 -*-

from decimal import Decimal
from django.db import models
from django.db.models import permalink

class Category(models.Model):
    name = models.CharField(max_length=60)
    slug = models.SlugField(max_length=60, unique=True)
    order = models.IntegerField(default=255)
    count_posts = models.IntegerField(default=0)

    class Meta:
        ordering = ['order']

    def __unicode__(self):
        return self.name

class SubCategory(models.Model):
    name = models.CharField(max_length=60)
    slug = models.SlugField(max_length=60)
    parent = models.ForeignKey(Category, null=True, blank=True, related_name='subcategories')
    count_posts = models.IntegerField(default=0)
    order = models.IntegerField(default=255)

    class Meta:
        unique_together = (('parent', 'slug'),)
        ordering = ['name']

    def __unicode__(self):
        return u'%s -> %s' % (self.parent, self.name)

class Post(models.Model):
    DENIED_STATUS = 0
    APPROVED_STATUS = 1
    PENDING_STATUS = 2

    POST_STATUS=(
        (DENIED_STATUS, 'Denied'),
        (APPROVED_STATUS, 'Approved'),
        (PENDING_STATUS, 'Pending'),
    )

    OFFER = 1
    DEMAND = 2
    SERVICES = 3
    RENTAL = 4
    ABSTRACT = 5
    VACANCY = 6

    POST_SUBJ=(
        (OFFER, u'Попит'),
        (DEMAND, u'Пропозиція'),
        (SERVICES, u'Послуги'),
        (RENTAL, u'Аренда'),
        (ABSTRACT, u'Резюме'),
        (VACANCY, u'Вакансії'),
    )

    category = models.ForeignKey(SubCategory)
    subj=models.IntegerField(u'Тип', max_length=1, choices=POST_SUBJ, default=OFFER)
    status=models.IntegerField(u'Стан', max_length=1, choices=POST_STATUS, default=APPROVED_STATUS)
    title = models.CharField(max_length=60)
    slug = models.SlugField(max_length=60)
    body = models.CharField(max_length=250)
    contact = models.CharField(max_length=120)
    email = models.CharField(max_length=100, null=True, blank=True)
    price = models.DecimalField(max_digits=8, decimal_places=2, default=Decimal('0.00'), )
    ip_address = models.IPAddressField(u'IP address', null=True, blank=True)
    youtube = models.CharField(max_length=100, null=True, blank=True)
    site_link = models.CharField(max_length=100, null=True, blank=True)
    posted_on = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['posted_on']

    def __unicode__(self):
        return u'%s' % self.title

    @permalink
    def get_absolute_url(self):
        return (
            'ogo_ogo', None, {
                'cat_slug':self.category.parent.slug,
                'sub_cat_slug':self.category.slug,
                'id':self.pk,
            })

    def formattedprice(self):
        return u'%01.2f' % self.price

    def save(self, *args, **kwargs):
        super(Post, self).save(*args, ** kwargs)
views.py
@render_to('')
def add(request, form_class=AddPostForm, template="add.html"):
    if request.method == "POST":
        form = form_class(request.POST)
        if form.is_valid():
            new_obj = form.save()
            return redirect(reverse('ogo_add_complete', kwargs={'id':new_obj.id,}))
    else:
        form = form_class()
    return {
        "form": form,
        }, template

@render_json
def fetch_subcat_json(request):
    result = list()

    try:
        cat = Category.objects.get(pk=int(request.GET.get('id', '')))
        sub_cat = SubCategory.objects.filter(parent=cat)

        result.append({ 'optionDisplay': '-- Оберіть категорію --', "optionValue" : '' })
        for sc in sub_cat:
            result.append({ 'optionDisplay': sc.name, "optionValue" : sc.pk })
    except:
        result.append({ 'optionDisplay': '-- Оберіть категорію --', "optionValue" : '' })
    return result
forms.py
# -*- coding:utf-8 -*-

from types import *
from django import forms
from django.utils.translation import ugettext_lazy as _, ugettext
from django.template.defaultfilters import slugify
from apps.ogo.models import Post, Category, SubCategory

class AddPostForm(forms.Form):
    category = forms.ChoiceField(required=True,)
    sub_category = forms.ChoiceField(required=True,)
    type_post = forms.ChoiceField(required=True,)
    title = forms.CharField(label=_(u'Заголовок'), max_length=100, widget=forms.TextInput())
    contact = forms.CharField(label=_(u'Конакт'), max_length=100, widget=forms.TextInput())
    body = forms.CharField(label=_(u"Текст оголошення"),max_length = 350, widget = forms.Textarea, required=True)
    contact = forms.CharField(label=_(u'Конакт'), max_length=100, widget=forms.TextInput())
    price = forms.CharField(label=_(u'Вартість, грн.'), max_length=10, widget=forms.TextInput(),required=True)

    def __init__(self, *args, **kwargs):
        super(AddPostForm, self).__init__(*args, **kwargs)

        self.sub_cat = SubCategory.objects.all()

        CAT_CHOICES = [('', '-- Оберіть --'), ] + [(c.pk, c.name) for c in Category.objects.all().order_by("pk")]
        SUBCAT_CHOICES = [('', '-- Оберіть категорію --'),]
        TYPE_CHOICES = [('', '-- Оберіть --'), ] + [(t[0], t[1]) for t in Post.POST_SUBJ]

        try:
            init_cat = int(args[0]['category'])
            SUBCAT_CHOICES = [('', '-- Оберіть --'), ] + [(c.pk, c.name) for c in SubCategory.objects.filter(parent=init_cat).order_by("pk")]
        except:
            init_cat = None

        try:
            init_sub_cat = int(args[0]['sub_category'])
            SUBCAT_CHOICES = [('', '-- Оберіть --'), ] + [(c.pk, c.name) for c in SubCategory.objects.filter(parent=init_cat).order_by("pk")]
        except:
            init_sub_cat = None

        try:
            init_type = int(args[0]['type_post'])
        except:
            init_type=None

        self.fields['category'] = forms.ChoiceField(choices=CAT_CHOICES, label=u'Категорія', initial=init_cat)
        self.fields['sub_category'] = forms.ChoiceField(choices=SUBCAT_CHOICES, label=u'Підкатегорія', initial=init_sub_cat)
        self.fields['type_post'] = forms.ChoiceField(choices=TYPE_CHOICES, label=u'Тип', initial=init_type)

    def save(self):
        return Post.objects.create(
            category = self.sub_cat.get(pk=self.cleaned_data["sub_category"]),
            subj = self.cleaned_data["type_post"],
            title = self.cleaned_data["title"],
            slug = slugify(self.cleaned_data["title"]),
            body = self.cleaned_data["body"],
            contact = self.cleaned_data["contact"],
            price = self.cleaned_data["price"],
        )
add.html
    

    
{{ form.non_field_errors }} {% for field in form %} {% endfor %}
{{ field.label_tag }}:
{{ field }} {{ field.errors }}
urls.py
# -*- coding:utf-8 -*-

from django.conf.urls.defaults import *

urlpatterns = patterns('ogo.views',
    url(r'^dodaty/', 'add', name = "ogo_add"),
    url(r'^dodano-uspishno/(?P\d{1,5})/$', 'add_complete', name = "ogo_add_complete"),
    url(r'^fetch-subcat/$', 'fetch_subcat_json', name = "fetch_subcat"),
)

Оновлення (RENEW) домену org.ua

Залишу шпаргалку для себе і може для когось.

to: register_query@org.ua
subject: RENEW domain.org.ua

domain:domain.org.ua
descr: domain homepage
admin-c:ваш_нік-UANIC
tech-c: ваш_нік-UANIC
nserver: ns1.ваш_днс
nserver: ns2.ваш_днс
changed: e-mail@e-mail.com 20121003
source: UANIC