Динамические кнопки, которые фильтруют объекты Django @UPDATE - PullRequest
0 голосов
/ 28 февраля 2019

@ ОБНОВЛЕНИЕ

Я хочу создать динамические несколько кнопок для фильтрации объектов, аналогично веб-сайту https://justjoin.it/brands

На данный момент я выполнил фильтрацию с помощью Django-filter Это позволяет пользователям фильтровать компании по типу, городу и является открытой компанией для студентов.Но этот django-фильтр требует обновления страницы, что означает, что это не динамическое обновление.Это выглядит так:

image 1 image 2

, и это функционально, работает отлично.

Тогда ясоздал простой API с django-rest-framework , который доступен для 127.0.0.1:8000/api/companies и выглядит так

Image

, а также отлично работает.

Следующее, что я сделал, это добавление jQuery и простого скрипта для получения данных из API, когда кто-то отправляет форму с ID=submit (изображение ниже)

image

Но теперь я застрял, потому что я не знаю, как получить данные из API и сравнить это с шаблоном.Я прошу любые предложения, потому что я не смог найти хорошего примера.

Мои файлы (обновлено)

models.py

from django.db import models
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from django.core.validators import MinValueValidator
from multiselectfield import MultiSelectField
import django_filters

TYPES = (
        ('Startup', 'Startup'),
        ('Software House', 'Software House'),
        ....)
CITIES = (
         ('Warszawa', 'Warszawa'),
         ('Poznan', 'Poznan'),
         ....)
COMPANY_TECHNOLOGIES = (
        ('PHP', 'PHP'),
        ('js', 'JavaScript'),
        ....)
STUDENTS = (
        ('No', 'No'),
        ('Yes', 'Yes')
    )
class Company(models.Model):
    name = models.CharField(max_length=100, blank=False)
    students = models.CharField(max_length=3, choices=STUDENTS)
    type = models.CharField(max_length=15, choices=TYPES)
    workers = models.PositiveIntegerField(validators=[MinValueValidator(1)])
    city = models.CharField(max_length=15,choices=CITIES)
    stack = MultiSelectField(choices=COMPANY_TECHNOLOGIES)
    ....

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

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.name        

views.py

from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from .models import Company
from .filters import CompanyFilter
from rest_framework import viewsets
from .serializers import CompanySerializer
# Create your views here.

def companies_list(request):
    my_companies = Company.objects.all()

    ## filter by company type
    type = request.GET.get('type')
    if type:
        my_companies = Company.objects.filter(type=type)
    ## filter by company city
    city = Company.objects.all()
    if city:
        my_companies = Company.objects.filter(city=city)
    ## filter by company technologies
    stack = request.GET.get('stack')
    if stack:
        my_companies = Company.objects.filter(city=city)

    my_companies = my_companies.order_by('published_date')
    return render(request, 'company/companies_list.html', {'my_companies': my_companies})

def comp_list(request):
    f = CompanyFilter(request.GET, queryset=Company.objects.all())
    return render(request, 'company/comp_list.html', {'filter': f})

##def brands(request, slug):
  ##  brands = Company.objects.all()
    ##return render(request, 'company/comp_view.html', {'brands': brands})

def brands(request, pk):
    brand = get_object_or_404(Company, pk=pk)
    return render(request, 'company/comp_view.html', {'brand': brand})

comp_list.html

{% extends 'company/base.html' %}
{% block content %}


    <div id="filter">
    <form action="" method="get" id="submit">
        {{ filter.form.as_p }}
        <input type="submit"/>
    </form>
    {% for obj in filter.qs %}
    <a href="/brands/{{obj.id}}">{{ obj.name }}</a>
        <p>Image {% if obj.image != None %}
        <img src="{{ obj.image.url }}">
        {% endif%}</p>
        <p>Icon {% if obj.icon != None %}
        <img src="{{ obj.icon.url }}" width="30" height="30">
        {% endif%}</p>

        <br> Type: {{  obj.type }} City: {{ obj.city }} Stack: {{  obj.stack }} 
         <br />
         <br>
    {% endfor %}
{% endblock %}

serializers.py

from .models import Company
from rest_framework import serializers

    class CompanySerializer(serializers.ModelSerializer):
        class Meta:
            model = Company
            fields = "__all__"

filters.py

import django_filters
from .models import Company, COMPANY_TECHNOLOGIES
from django_filters import ChoiceFilter

    class CompanyFilter(django_filters.FilterSet):

        class Meta:
            model = Company
            fields = ['type', 'city', 'students']

        def __init__(self, *args, **kwargs):
            super(CompanyFilter, self).__init__(*args, **kwargs)
            self.filters['type'].extra.update(
                {'empty_label': 'All'})
            self.filters['city'].extra.update(
                {'empty_label': 'All'})
            self.filters['students'].extra.update(
                {'empty_label': 'All'})

ajax.js

$( "#submit" ).click(function(event) {
event.preventDefault();

    $.ajax({
        url: "http://127.0.0.1:8000/api/companies/",
        method: 'GET',
        success: function(data){
        console.log(data)
        },
        error: function(error_data){
        console.log("error")
        console.log(error_data)
        }
        })});

1 Ответ

0 голосов
/ 28 февраля 2019

Фильтрация обычно выполняется с помощью параметров GET.

В этом примере, если вы добавите ?company_name=acme к URL-адресу, будут показаны только названия компаний с акме в имени:

def companies_list(request):
    my_companies = company.objects.filter(
        published_date__lte=timezone.now())

    company_name = request.GET.get('company_name', None)
    if company_name:
        my_companies = my_companies.filter(company_name__icontains=company_name)

    my_companies = my_companies.order_by('published_date')
    return render(request, 'company/index.html', {'my_companies': my_companies})

Существует также django-фильтр для облегчения этой вещи.

Что касается SPA, то это выходит за рамки вопроса, но это должно быть сделано с помощью запроса AJAX и заменыЭлемент DOM с ответом представления или возвратом JSONResponse и созданием элемента с помощью JavaScript.

...