问题描述
我正在尝试使用Django和React作为前端来构建API服务器。
我在用来在React页面上显示出版物的ID遇到问题。我的目标是显示“是,否”背景(例如,黑色,白色,黑色,白色...)。
到目前为止,在React中,我已经做到了:
{news && news.list.map((item) => {
return(
<NewsPiece
key={item.id}
title={item.title}
active={item.id % 2 === 0 ? true : false} #when active,white,otherwise black
/>
)
})}
这是我在Django中的模态。
class Publication(models.Model):
title = models.CharField(max_length=250,blank=False,null=False)
subTitle = models.CharField(max_length=500,blank=True,null=True)
author = models.CharField(max_length=100,null=True)
inter = models.BooleanField(default=False,null=True) #if my publication is in english or not
created_at = models.DateTimeField(default=timezone.now)
下面是我的序列化器:
class PublicationMiniSerializer(serializers.ModelSerializer):
newsPaper = NewsPaperSerializer(many=False)
columnist = ColumnistSerializer(many=False)
class Meta:
model = Publication
fields = ('title','id','created_at')
这是我的数据库外观的简短示例:
------
id: 1 #display color would be black as id % 2 === 0 is false
Title: esse é o título #(this is the title in pt-br :))
inter: false
------
id: 2 #display color would be white
Title: this is the title
inter: True
------
id: 3 #display black
Title: esse é o título #(this is the title in pt-br :))
inter: False
------
id: 4 #display white
Title: this is the title
inter: True
如果我尝试在两种类型上都显示此内容(当inter为false和true时),则可以正常工作。 id是连续的,我可以根据自己的条件使反应使用黑白(id%2 === 0?true:false)。
但是我的目标是可以选择按国际参数过滤出版物。因此,如果过滤器等于“ inter == True”,我会得到这个。
------
id: 2 #display color would be white
Title: this is the title
inter: True
------
id: 4 #display white
Title: this is the title
inter: True
在这种情况下,我将拥有白色和白色。
测试1: 我首先尝试更改React组件的行为。我没有传递ID,而是使用循环号。
{news && news.list.map((item,i) => {
return(
<NewsPiece
key={item.id}
title={item.title}
active={i % 2 === 0 ? true : false} #when active,black,otherwise white
/>
)
})}
这会起作用,但这不是一个好方法,因为当我在此组件上进行某些更改(例如,在开头添加一个新元素)时,它将再次重新加载所有内容。
测试1(到目前为止,我一个人走得最远)
我更改了模态的行为,并追加了两个字段:inter_id和national_id。
class Publication(models.Model):
title = models.CharField(max_length=250,null=True)
inter = models.BooleanField(default=False,null=True)
created_at = models.DateTimeField(default=timezone.now)
inter_id = models.IntegerField(null=True)
national_id = models.IntegerField(null=True)
def __str__(self):
return self.title
def save(self,*args,**kwargs):
top = Publication.objects.order_by('-id').filter(inter=self.inter)[0]
if self.inter:
self.inter_id = top.inter_id + 1
else:
self.national_id = top.national_id + 1
super().save(*args,**kwargs)
当我保存发布项目时,将调用save方法。然后,我为国际和国家创建一个“假ID”。 id将根据“ inter”字段(真或假)进行设置。我认为这部分是不言自明的。
并跟随我的序列化器。
class PublicationMiniSerializer(serializers.ModelSerializer):
newsPaper = NewsPaperSerializer(many=False)
columnist = ColumnistSerializer(many=False)
id = serializers.SerializerMethodField()
class Meta:
model = Publication
fields = ('title','headLine','newsPaper','columnist','created_at')
def get_id(self,obj):
if obj.inter:
return obj.inter_id
return obj.national_id
在这段代码中,我改写了我的ID,以便根据条件“ if inter == true”代表我的inter_id或national_id。我很高兴实现这一目标。这样,“ id”将代表nationala_id和international_id(并且两个变量都将“计数”数据库中的位置)。
我的问题是: 对于我的解决方案,每次添加出版物以查找最后的国际或国家/地区ID时,我都必须再次进行查询。我不太喜欢这个……我想我可以做得更好。
问题:
我想知道是否有一种方法可以将对象在序列化程序查询中的当前位置传递给序列化程序。
例如。
我的查询有20个项目。从0到20。第一个元素的ID为0,最后一个元素的ID为20。在下一个页面21至40上,第一个元素的ID为21 ...
有没有办法做到这一点? 你们有更好的方法吗?
希望我让自己明白了。 如果您有任何疑问,请让我知道,我会尝试用其他方式进行解释。 非常感谢!
解决方法
经过研究,我发现了一种更简单的方法。我当时想得太多,却忘了使用最明显的方法:CSS
我使用even and odd options in CSS而不是尝试使用id来定义线条的颜色。因此,不必处理django-rest-framework中的所有内容或与我的react代码混淆。
这是我的react元素:
{news && news.list.map((item) => {
return(
<NewsPiece
key={item.id}
title={item.title}
#####active={item.id % 2 === 0 ? true : false} #when active,white,otherwise black
/>
)
})}
NewsPiece是使用样式组件创建的
要处理奇数和偶数,我创建了另一个元素Section,并将NewsPiece包装在其中。实际上,我的NewsPiece元素是一个带有标题的“ li”。
这是我的部分。
import styled from 'styled-components';
const Section = styled.section`
li:nth-child(even){
background: black;
border-radius: 10px;
}
li:nth-child(odd){
background: white;
}
`;
这样,我无需更改后端和前端反应代码中的一行就可以实现我想要的东西。