Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Selektovanje najspecifičnije potkategorije

[es] :: Python :: Selektovanje najspecifičnije potkategorije

[ Pregleda: 755 | Odgovora: 1 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

clydefrog

Član broj: 340220
Poruke: 107



+5 Profil

icon Selektovanje najspecifičnije potkategorije30.09.2019. u 16:01 - pre 55 meseci
Implementujem 'chained dependent combobox selection', dakle počinje se sa jednim combobox-om za glavnu kategoriju, i kada se selektuje glavna kategorija, pojavljuje se još jedan <select> za selektovanje potkategorije, i tako dalje sve dok se najspecifičnija, najuža kategorija ne izabere.

Ovo trenutno radi ovako: kad god se vrednost u combobox-u promeni, šalje se AJAX request koji poziva view koji renderuje još jedan <select> ako kategorija ima 'dece', u suprotnom vraća HttpResponse koji prestaje da 'kači' listener. Koristim django-mptt da modelujem svoje kategorije.

Dakle, imam jedan view za dodavanje proizvoda i hoću da budem siguran da je najuža kategorija (mora da bude leaf node) selektovana i da dodelim tu kategoriju svojoj Product instanci.

Evo ga taj view:

Code:
@login_required
def product_create_view(request):
    if request.method == 'POST':
        create_product_form = CreateProductForm(request.POST)
    else:
        create_product_form = CreateProductForm()
    return render(request, 'products/product_create.html', {'form': create_product_form})


Evo je forma:

Code:
from django.forms import ModelForm
from .models import Product, Category


class CreateProductForm(ModelForm):

    class Meta:
        model = Product
        fields = (
            'title',
            'description',
            'price',
            'year',
            'category',
        )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['category'].queryset = Category.objects.filter(parent=None)


products/product_create.html:
Code:

{% extends 'pages/base.html' %}

{% block content %}
<h1>Create a product</h1>
<form method='POST' id='productForm' data-products-url="{% url 'products:ajax_load_categories' %}">
    <label>Title</label>
    {{ form.title }}
    <label>Description</label>
    {{ form.description }}
    <label>Price</label>
    {{ form.price }}
    <label>Year</label>
    {{ form.year }}
    <label>Category</label>
    {{ form.category }}
</form>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    var $r_ = function() {
        var url = $("#productForm").attr("data-products-url");
        var categoryId = $(this).val();
        var toRemove = $(this).nextAll('select');
        $.ajax({                       
          url: url,                    
          data: {
            'category': categoryId
          },
          success: function (data) {
            if (data != 'leaf_node') {
              toRemove.remove();
              $("#productForm").append(data);
            }
            else {
              toRemove.remove();
            }
          }
        });  
    } //end of $r_
    $(document).on('change', 'select', $r_);
</script>
{% endblock %}


Ovo je ajax_load_categories view:
Code:

def load_categories(request):
    category_id = request.GET.get('category')
    subcategories = Category.objects.get(id=category_id).get_children()
    if subcategories:
        return render(request, 'products/category_dropdown_list_options.html', {'subcategories': subcategories})
    return HttpResponse('leaf_node')


products/category_dropdown_list_options.html:

Code:
<select>
    <option value="">---------</option>
    {% for subcategory in subcategories %}
        <option value="{{ subcategory.pk }}">{{ subcategory.name }}</option>
    {% endfor %}
</select>


I za svaki slučaju Category model:

Code:
class Category(MPTTModel):
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    name = models.CharField(max_length=255)
    slug = models.SlugField()
    
    class Meta:
        unique_together = (('parent', 'slug',))
        verbose_name_plural = 'categories'
   
    class MPTTMeta:
        order_insertion_by = ['name']

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def get_slug_list(self):
        ancestors = self.get_ancestors(include_self=True)
        slugs = [ancestor.slug for ancestor in ancestors]
        new_slugs = []
        for idx, ancestor in enumerate(slugs, 1):
            new_slugs.append('/'.join(slugs[:idx]))
        return new_slugs

    def get_recursive_product_count(self):
        return Product.objects.filter(category__in=self.get_descendants(include_self=True)).count()


 
Odgovor na temu

clydefrog

Član broj: 340220
Poruke: 107



+5 Profil

icon Re: Selektovanje najspecifičnije potkategorije30.09.2019. u 16:22 - pre 55 meseci
Nađoh jedno rešenje, ne znam kako vam se čini:

Code:
def load_categories(request):
    category_id = request.GET.get('category')
    request.session['category'] = category_id
    subcategories = Category.objects.get(id=category_id).get_children()
    if subcategories:
        return render(request, 'products/category_dropdown_list_options.html', {'subcategories': subcategories})
    return HttpResponse('leaf_node')


Code:
@login_required
def product_create_view(request):
    if request.method == 'POST':
        create_product_form = CreateProductForm(request.POST)
        if create_product_form.is_valid():
            product = create_product_form.save(commit=False)
            product.category = Category.objects.get(id=request.session.get('category'))
            product.save()
    else:
        create_product_form = CreateProductForm()
    return render(request, 'products/product_create.html', {'form': create_product_form})



Dakle id kategorije stavljam u session, i onda potom dohvatam kategoriju sa tim ID-em nakon submit-a.
 
Odgovor na temu

[es] :: Python :: Selektovanje najspecifičnije potkategorije

[ Pregleda: 755 | Odgovora: 1 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.