python - 在 Django Rest 框架中获取图像字段绝对路径 - 非请求流
问题描述
我有一个周期性的 celery 任务,它需要将对象的表示存储在特定的 json 字段中。
这是简化的模型结构。父 <-- ChildWrapper <-- 子图像
所以基本上我有一个'ChildImage'模型指的是'ChildWrapper',它又指的是'Parent'。
class Parent(TimeStampedModel):
label = models.CharField(max_length=30, unique=True)
live_content = JSONField(blank=True, null=True)
is_template = models.BooleanField(default=False)
reference_image = models.ImageField(upload_to=get_web_row_reference_image_path, blank=True, null=True)
# Around 8 Other Fields
def __str__(self):
return '%s' % self.label
class ChildWrapper(TimeStampedModel):
name = models.CharField(max_length=25, blank=True, null=True)
row = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='web_column')
order = models.PositiveIntegerField(default=0)
# Around 20 Other Fields
def __str__(self):
return '%s' % self.name
class ChildImage(TimeStampedModel):
image = models.ImageField(upload_to=get_web_image_path)
column = models.ForeignKey(ChildWrapper, on_delete=models.CASCADE, related_name='web_image')
# Around 10 Other Fields
def __str__(self):
return '%s' % self.column
这是为模型定义的序列化程序。
class ChildImageSerializer(serializers.ModelSerializer):
class Meta:
model = ChildImage
fields = '__all__'
class ChildWrapperSerializer(serializers.ModelSerializer):
web_image = ChildImageSerializer(read_only=True, many=True)
class Meta:
model = ChildWrapper
fields = '__all__'
class ParentSerializer(serializers.ModelSerializer):
web_column = ChildWrapperSerializer(many=True, read_only=True)
class Meta:
model = Parent
fields = '__all__'
这是执行所需的定期芹菜任务
@app.task(bind=True)
def update_data(self):
# Get Parent By a condition.
parent = Parent.objects.filter(to_update=True).first()
parent.live_content = None
parent.live_content = ParentSerializer(parent).data
print(parent.live_content)
parent.save()
上面的任务得到子图像的输出,像这样,图像字段是相对路径而不是绝对路径。
{
"id": 1
"image": '/api/col/info.jpg'
}
有什么方法可以获取图像字段的绝对路径?
{
"id": 1
"image": "http://localhost:8000/admin/media/api/col/info.jpg"
}
PS: 我不能将请求上下文作为ParentSerializer(parent, context={'request': request})传递给序列化程序,因为这里不涉及请求对象。
解决方案
我认为您有两种方法可以解决此问题。
第一个,是通过请求。您可以采用这种方法:
class ChildImageSerializer(serializers.ModelSerializer):
img_url = serializers.SerializerMethodField()
class Meta:
model = ChildImage
fields = '__all__'
def get_img_url(self, obj):
return self.context['request'].build_absolute_uri(obj.image.url)
class ChildWrapperSerializer(serializers.ModelSerializer):
web_image = serializers.SerializerMethodField()
class Meta:
model = ChildWrapper
fields = '__all__'
def get_web_image(self, obj):
serializer_context = {'request': self.context.get('request') }
children = ChildImage.objects.filter(row=obj)
serializer = ChildImageSerializer(children, many=True, context=serializer_context)
return serializer.data
class ParentSerializer(serializers.ModelSerializer):
web_column = serializers.SerializerMethodField()
class Meta:
model = Parent
fields = '__all__'
def get_web_column(self, obj):
serializer_context = {'request': self.context.get('request') }
children = ChildWrapper.objects.filter(row=obj)
serializer = ChildWrapperSerializer(children, many=True, context=serializer_context)
return serializer.data
在这里,我SerializerMethodField
用来将请求传递给下一个序列化程序。
第二种方法是使用Django Sites Framework
(@dirkgroten 提到)。您可以执行以下操作:
class ChildImageSerializer(serializers.ModelSerializer):
img_url = serializers.SerializerMethodField()
class Meta:
model = ChildImage
fields = '__all__'
def get_img_url(self, obj):
return 'http://%s%s%s' % (Site.objects.get_current().domain, settings.MEDIA_URL, obj.img.url)
更新:我完全错过了芹菜部分。对于生产,我认为您不必担心它们在 S3 中,绝对路径应该来自obj.image.url
. 在 dev 和 stage 中,您可以使用给定的示例获取绝对路径。所以,试试这样:
class ChildImageSerializer(serializers.ModelSerializer):
img_url = serializers.SerializerMethodField()
class Meta:
model = ChildImage
fields = '__all__'
def get_img_url(self, obj):
if settings.DEBUG: # debug enabled for dev and stage
return 'http://%s%s%s' % (Site.objects.get_current().domain, settings.MEDIA_URL, obj.img.url)
return obj.img.url
或者,有一种方法可以django-crequest
在 celery 中使用请求,但我不确定它是否方便您。
推荐阅读
- angular7 - Angular-Calendar 上下文菜单不起作用如何调出?
- python - 将图像从文件夹 python 导入到 numpy 数组列表
- java - 当我在 iOS appium 中从本机切换到 webview 上下文时,Appium 驱动程序正在获取与当前页面 url 不同的 url
- sql - 从 json 插入 sql server 表(2016)
- python - 即使使用多种方法也无法重塑 Numpy 数组
- javascript - 如何将两个以上的参数传递给模态 ng2 bootstrap
- angular - 服务 index.html 后服务器没有路由到 /login
- python - 如何在 igraph python 中读取文件和计算图形属性
- python - argparse 选择一个默认的附加参数
- node.js - 如何使 ES6 类对 Node JS 中的服务器和客户端脚本可见?