django chained select box

979 views Asked by At

trying to accomplish a fairly simple chained select following this example. this was the most fitting example i could find for my limited requirements and figured it only needed some renaming to match my setup.

models.py

class Category(models.Model):
    """Category"""
    name = models.CharField(max_length=50)
    slug = models.SlugField()


    def save(self, *args, **kwargs):
                # Uncomment if you don't want the slug to change every time the name changes
                #if self.id is None:
                        #self.slug = slugify(self.name)
                self.slug = slugify(self.name)
                super(Category, self).save(*args, **kwargs)
    def __unicode__(self):
        return self.name
#        return u'%s' % (self.name)

class SubCategory(models.Model):
    """Sub Category"""
    category = models.ForeignKey(Category)
    name = models.CharField(max_length=50)
    slug = models.SlugField()

    def save(self, *args, **kwargs):
                # Uncomment if you don't want the slug to change every time the name changes
                #if self.id is None:
                        #self.slug = slugify(self.name)
                self.slug = slugify(self.name)
                super(SubCategory, self).save(*args, **kwargs)

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

class Website(models.Model):
    """ service website."""
    url = models.URLField(validators=[validate_onion_url], unique=True)
    # service
    id = models.CharField(primary_key=True, max_length=16,
    validators=[MinLengthValidator(16), MaxLengthValidator(16)], unique=True)
    #is this domain banned
    banned = models.BooleanField(default=False)
    #is it online or offline
    online = models.BooleanField(default=False)
    #echo -e "BLAHBLAHBLAH.onion\c" | md5sum
    #hashlib.md5(url[8:-1]).hexdigest()
    md5 = models.CharField(max_length=32,
    validators=[MinLengthValidator(32), MaxLengthValidator(32)], unique=True)
    updated = models.DateTimeField(auto_now=True, auto_now_add=True)
    sub_categories = models.ForeignKey(SubCategory, default=1)
    referral = models.TextField(blank=True)
    class Meta:
        """Meta class."""
        app_label = 'ahmia'
    def __unicode__(self):
#        return self.url
        return u'%s' % (self.url)

and views.py

@require_GET
def category_browser(request):
    """Browser Page"""
    categories = Category.objects.all().prefetch_related('subcategory_set')
    subcategories = SubCategory.objects.filter(category=categories)
    return render(request, 'browser.html', {'categories': categories, 'subcategories': subcategories)

def getdetails(request):
    #country_name = request.POST['country_name']
    subcategory_name = request.GET['cnt']
    print "ajax subcategory_name ", subcategory_name

    result_set = []
    all_websites = []
    answer = str(subcategory_name[1:-1])
    selected_subcategory = SubCategory.objects.get(name=answer)
    print "selected subcategory name ", selected_subcategory
    all_websites = selected_subcategory.website_set.all()
    for website in all_websites:
        print "website name", website.url
        result_set.append({'name': website.url})
    return HttpResponse(simplejson.dumps(result_set), mimetype='application/json', content_type='application/json')

and the html template

<html>
    <head>
    <script type="text/javascript" src="/static/js/jquery-latest.min.js"></script>
    <script type="text/javascript" src="/static/js/script.js"></script>
        <script>
            $(document).ready(function(){
                 $('select#selectsubcategories').change(function () {
                     var optionSelected = $(this).find("option:selected");
                     var valueSelected  = optionSelected.val();
                     var subcategory_name   = optionSelected.text();


                     data = {'cnt' : subcategory_name };
                     ajax('/getdetails',data,function(result){

                            console.log(result);
                            $("#selectwebsites option").remove();
                            for (var i = result.length - 1; i >= 0; i--) {
                                $("#selectwebsites").append('<option>'+ result[i].url +'</option>');
                            };


                         });
                 });
            });
        </script>
    </head>

    <body>
        <select name="selectsubcategories" id="selectsubcategories">
    <option value="" selected="selected">Select Category</option>
    {% for category in categories %}
            <optgroup label="{{ category.name }}">
        {% for item in category.subcategory_set.all %}
            <option val="{{ item.name }}"> {{ item.name }} </option>    
        {% endfor %}
            </optgroup>
    {% endfor %}
        </select>   


        <select name ="selectwebsites" id="selectwebsites">
       </select>

    </body>
</html>

The first select box showing category/subcategory works as expected, however the second select box remains empty whatever subcategory selected.

No errors that i can see and no idea how to debug this.

I assume the example followed is a perfectly fine working solution, and i suspect the problem is somewhere in my naming scheme e.g. am i mixing up subcategory and sub_category somewhere in referring to my foreignkey? but i might be wrong,

much obliged!

EDIT:

found an error, in my http log i can see a call is made to /getdetails , that makes sense. However after adding /getdetails in urls.py i still get a 500 error in my http log

# Browser Page
urlpatterns += patterns('',
    (r'^browser/', 'rango.views.category_browser'),
    (r'^getdetails/', 'rango.views.getdetails'),
)
1

There are 1 answers

0
adamzia On

sorry to answer my question post so quickly,

adding the /getdetails to url.py solves part of the problem, this was not mentioned in the original example.

# Browser Page
urlpatterns += patterns('',
    (r'^browser/', 'rango.views.category_browser'),
    (r'^getdetails/', 'rango.views.getdetails'),
)

and remove from views.py

mimetype='application/json',

as this is depreciated in django 1.7 it seems