首页 > 编程问答 >搜索请求后,属性名称已更改为属性 ID,如何解决?

搜索请求后,属性名称已更改为属性 ID,如何解决?

时间:2024-08-06 15:53:18浏览次数:7  
标签:javascript python django react-native

我在前端使用 React Native Expo Web 应用程序,在后端使用 Django。

我有一个运行良好的搜索功能。但我面临的问题是,在搜索项之后,特定动物的属性名称已更改为属性 id(数字)。

我的意思是,在手风琴中显示类别名称。但搜索后会显示类别 ID。

在前端我有一个具有一些属性的手风琴。类别的属性看起来:

export const AccordionItemsProvider = ({ children }) => {   
    const [categoryExpanded, setCategory] = useState(false);
    

    const accordionItems = (item) => {
        return (
            <>
            
                <List.Accordion
                    title="Familie"
                    expanded={categoryExpanded}
                    onPress={() => setCategory(!categoryExpanded)}>
                    <Text>{item.category}</Text>
                </List.Accordion>
                
            </>
        );
    };

    return (
        <AccordionItemsContext.Provider
            value={{
                accordionItems,
            }}>
            {children}
        </AccordionItemsContext.Provider>
    );
};

因此将显示类别的名称。但搜索后会显示类别的 id。而不是名称。

动物的搜索上下文看起来:

/* eslint-disable prettier/prettier */

import React, { createContext, useEffect, useState } from "react";

import { fetchAnimalData } from "./animal/animal.service";
import useDebounce from "../hooks/use-debounce";

export const SearchAnimalContext = createContext();
export const SearchAnimalContextProvider = ({ children }) => {
    const [searchAnimal, setSearchAnimal] = useState([]);
    const [results, setResults] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const [input, setInput] = useState("");
    const debounce = useDebounce(input, 500);

    useEffect(() => {
        if (debounce === "") {
            setResults([]);
            return;
        }
        fetchAnimalData(debounce)
            .then((response) => {
                setResults(response);
            })
            .catch((err) => {
                setError(err);
            });

        fetchAnimalData();
    }, [debounce]);

    const performSearch = async (text) => {
        if (text.trim() === "") {
            setResults([]);
        }
        setLoading(true);
        setError(null);
        setTimeout(() => {
            fetchAnimalData(text)
                .then((response2) => {
                    setResults(response2);
                    console.log(response2);

                    setLoading(false);
                })
                .catch((err) => {
                    setLoading(false);
                    setError(err);
                });
        }, 100);
    };
    return (
        <SearchAnimalContext.Provider
            value={{
                results,
                setResults,
                searchAnimal,
                setSearchAnimal,
                input,
                setInput,
                performSearch,
                loading,
                error,
            }}>
            {children}
        </SearchAnimalContext.Provider>
    );
};

console.log 的搜索请求之后的输出看起来:

category
: 
30
category_name
: 
"Katachtigen - Felidae"

所以在搜索之前它只是类别。但在搜索请求之后。 api 列表中添加了一个category_name。如果我记录handleSearchChange函数:

    const handleSearchChange = (text) => {
        setInput(text);
        if (text.length === 0) {
            performSearch(""); // Clear results when the input is empty
            navigation.navigate("dieren");
        } else {
            performSearch(text);
            console.log(results);
        }
    };
category
: 
18
category_name
: 
"Eekhoorns - Sciuridae"

那么在正确显示搜索类别之前:“Katachtigen - Felidae”。但是在搜索请求类别显示为 30 - Category_id: 后,这是不正确的。

组件中的 search 函数看起来:

import React, { useContext, useEffect, useState } from "react";
import { SafeArea } from "../../../components/utility/safe-area.component";
import { SearchAnimalContext } from "../../../services/search-animal.context";
import { fetchSubCategoryData } from "../../../services/category/category.service";

export const SubCategoryScreen = ({ route, navigation }) => {
    
    const [isLoading, setLoading] = useState(true);
    const { performSearch, results, setInput, input } = useContext(SearchAnimalContext);    
    const [isSearchbarFocused, setSearchbarFocused] = useState(false);  

    useEffect(() => {
        fetchSubCategoryData(route.params.subcategories).then((data) => {
            setSubCategoryList(data.animals.length > 0 ? data.animals : data.subcategories);
            setLoading(false);
        });
    }, [route]);

    const handleSearchChange = (text) => {
        setInput(text);
        if (text.length === 0) {
            performSearch(""); 
            navigation.navigate("dieren");
        } else {
            performSearch(text);
        }
    };



    return (
        <SafeArea>
            {isLoading && (
                <LoadingContainer>
                    <ActivityIndicator animating={true} color={MD2Colors.green200} />
                </LoadingContainer>
            )}
            <Searchbar
                placeholder="Search animals"
                value={input}
                onFocus={() => setSearchbarFocused(true)}
                onChangeText={handleSearchChange}
                onBlur={() => setSearchbarFocused(false)}
                style={styles.searchbar}
            />
            
        </SafeArea>
    );
};

这是搜索请求的 api 调用:

/* eslint-disable prettier/prettier */

import { API_URL } from "@env";
import { retrieveToken } from "../../services/authentication/token";

export const fetchAnimalData = async (text) => {
    const token = await retrieveToken();
    try {
        if (token) {
            const response = await fetch(`${API_URL}/api/animals/?search=${text}`, {
                method: "GET",
                headers: {
                    Authorization: `Token ${token}`,
                    Accept: "application/json",
                    "Content-Type": "application/json",
                },
            });
            return await response.json();
        } else {
            throw new Error(token);
        }
    } catch (error) {
        console.error("There was a problem with the fetch operation:", error);
        throw error;
    }
};

以及模型Animal 从后端看起来:

import sys
from io import BytesIO
from django.db import models

class Animal(models.Model):   
    name = models.CharField(max_length=100, verbose_name="Naam")
    sort = models.CharField(max_length=100, default='',  
    category = models.ForeignKey(
        Category, related_name='animals', on_delete=models.CASCADE, verbose_name="Familie")   

    def category_name(self):
        return self.category.name
   

    class Meta:
        verbose_name = "Dier"
        verbose_name_plural = "Dieren"
        # permissions = [("set_display_flag", "Check name is display or not",)]

   
        super(Animal, self).save()

    def __str__(self):
        return self.name

如何在搜索请求后显示正确的类别名称而不是类别 id?


问题在于搜索请求返回的数据结构与初始数据结构不同。在搜索请求后,API 响应包含 category 作为 ID,以及一个名为 category_name 的新字段,其中包含实际的类别名称。

需要更新前端代码以处理这种差异。可以通过以下两种方式之一实现:

1. 更新 AccordionItems 组件以使用 category_name :

const accordionItems = (item) => {
  return (
    <>
      <List.Accordion
        title="Familie"
        expanded={categoryExpanded}
        onPress={() => setCategory(!categoryExpanded)}
      >
        <Text>{item.category_name || item.category}</Text> 
      </List.Accordion>
    </>
  );
};

此代码首先检查 category_name 属性是否存在。如果存在,则使用它。否则,它将回退到 category 属性。

2. 更新 API 响应以始终包含类别名称:

还可以更新 Django API,以始终在响应中包含类别名称,即使在搜索请求中也是如此。这将使的前端代码更简单,因为它不需要处理不同的数据结构。

可以通过修改 Django 模型的序列化器来实现此目的。以下是一个示例:

from rest_framework import serializers

class AnimalSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name', read_only=True)

    class Meta:
        model = Animal
        fields = '__all__'

此序列化器将始终包含一个名为 category_name 的字段,该字段从 category 关系中获取其值。

选择哪种方法取决于的具体需求和偏好。如果可以控制 API,则更新 API 响应以始终包含类别名称可能会更简洁。但是,如果无法更改 API,则更新 AccordionItems 组件以处理不同的数据结构是一种有效的解决方法。

标签:javascript,python,django,react-native
From: 78835022

相关文章

  • python SQLite 访问组件
    importosimportsqlite3fromsqlite3importErrorfromqueueimportQueue,EmptyfromtypingimportList,Tuple,AnyclassSQLiteDB:default_db_path=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))default_db_file=default_db_path......
  • Python 卡在第 1 页
    让它读取下一页结果的最佳方法是什么?目前正在拉取数据,但只有第1页importrequestsimportjsonpage=1url="https://api-prod.grip.events/1/container/4368/search?search=&sort=name&order=asc&type_id=4907,4906,5265,4964,4904,1026,4908&page=%d"headers={......
  • 无法反序列化解码 JWT python 时的关键数据
    我正在使用pyjwt库来解码JWT令牌。我在解码时遇到此错误。代码在文档中给出。importjwtencoded_jwt='''eyJ0eXAiOiJKV1QiLCJhbG......'''secret=b''''-----BEGINPUBLICKEY-----MIIFRjCCBC6gAwIBAgIQCIdSGhpikQCjOIY154XoqzANBgkqhkiG9......
  • Python科研武器库 - 字符串操作 - 字符串开头结尾判断 startswith() endswith()
    使用场景:按照开头的前缀、结尾的后缀来判断、筛选目标字符串。使用函数:str.startswith(search_string,start,end)str.endswith(search_string,start,end)search_string:要匹配的目标字符串。start:要从中匹配search_string的str的起始索引。end:要考虑匹配的str的结......
  • 我正在 python 中使用 aspose.pdf 将 pdf 转换为 excel 。但问题是它只能将 pdf 的前
    `从tkinter导入*将aspose.pdf导入为ap从tkinter导入文件对话框importpandasaspdinput_pdf=filedialog.askopenfilename(filetypes=(("PDF文件",".pdf"),("所有文件",".")))output_file=filedialog.asksaveasfil......
  • 如何在selenium python中访问电子邮件中的所有文件夹
    我使用imaplib库,但有时无法访问某些帐户,我使用poplib但它只支持访问主邮箱,但不支持访问其他文件夹,如垃圾邮件我想使用imaplib,但不会出现有时甚至无法访问的错误尽管我有一个帐户,但我仍然可以访问它,或者是否有另一个库可以快速支持该帐户?你想要使用Selenium和Python......
  • python安装torch-cluster、torch-scatter、torch-sparse和torch-geometric | torch_ge
    1.检查CUDA版本【方法1】用nvidia-smi已装cuda,用nvidia-smi或nvcc-V查看【方法2】用torch已装torch,用torch代码打印importtorchprint(torch.__version__)#查看pytorch安装的版本号print(torch.cuda.is_available())#查看cuda是否可......
  • 计算机毕业设计django+vue出租车服务管理信息系统【开题+论文+程序】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加速和共享经济的兴起,出租车服务行业正经历着前所未有的变革。传统出租车行业面临着调度效率低下、乘客体验不佳、车辆管......
  • 计算机毕业设计django+vue校园网络跳蚤市场系统的设计与应用【开题+论文+程序】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的普及和校园生活的丰富多彩,学生们在日常学习和生活中积累了大量的二手物品,如书籍、电子产品、生活用品等。这些物品往往因为......
  • Python:学生成绩管理系统(大学编程期末实验)
    引言在这个信息时代,教育管理的自动化已成为提高效率的关键。本文将介绍如何使用Python开发一个学生成绩管理系统,旨在简化成绩记录、查询和分析的过程。创作灵感来源本项目灵感来源于我在教育机构的工作经历,以及对提高教育管理效率的持续追求。通过复盘过往项目,我意识到一个......