筛选对象Django @UPDATE

时间:2019-02-28 12:36:17

标签: django django-rest-framework django-filter

@UPDATE

我想制作动态的多个按钮来过滤对象,类似于网站https://justjoin.it/brands

目前,我已经使用 Django-filter 进行了过滤,该过滤器允许用户按类型,城市过滤公司,并且公司对学生开放。但这 django-filter 需要刷新页面,这意味着它不是动态更新。看起来像这样

image 1 image 2

这是实用的,效果很好。

然后我使用 django-rest-framework 创建了简单的API,该API可在127.0.0.1:8000/api/companies上使用,并且看起来像这样

Image

也可以。

接下来我要做的是当有人使用ID=submit提交表单时添加jQuery和简单脚本以从API获取数据(下图)

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 :(得分:0)

过滤通常是通过GET参数完成的。

在此示例中,如果将?company_name=acme添加到URL,则只会显示名称中带有acme的公司名称:

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-filter可以简化这些工作。

对于SPA来说,这超出了问题的范围,但是应该使用AJAX请求并用视图的响应替换DOM元素,或者返回JSONResponse并使用JavaScript构建该元素。 / p>