[英]Resolve Django/DRF ImageField URL from F() function
我有一个用例,如果图像 URL 存在于我们的数据库中,我会尝试覆盖它。
这是通过F()
查询获取ImageField
的查询集部分。
preferred_profile_photo=Case(
When(
# agent not exists
Q(agent__id__isnull=False),
then=F("agent__profile__profile_photo"),
),
default=Value(None, output_field=ImageField()),
)
Case-When 可以正确解决,但问题是从F("agent__profile__profile_photo")
返回的值不是 UI 可以使用的 URL。 相反,它类似于: "agentphoto/09bd7dc0-62f6-49ab-blah-6c57b23029d7/profile/1665342685--77e51d9c5asdf345364f774d0b2def48.jpeg"
Typically, I'd retrieve the URL via agent.profile.profile_photo.url
, but I receive the following when attempting to perform preferred_profile_photo.url
: AttributeError: 'str' object has no attribute 'url'
.
我试过包装Value(..., output_field=ImageField())
没有运气。
这里的关键是从 F() 解析后从 ImageField 中检索 url
作为参考,我正在使用storages.backends.s3boto3.S3Boto3Storage
。
感谢任何帮助!
我能够使用这篇文章中的一些信息来实现这一点。
这是我用来实现的助手function:
from django.core.files.storage import get_storage_class
def get_media_storage_url(file_name: str) -> str:
"""Takes the postgres stored ImageField value and converts it to
the proper S3 backend URL. For use cases, where calling .url on the
photo field is not feasible.
Args:
file_name (str): the value of the ImageField
Returns:
str: the full URL of the object usable by the UI
"""
media_storage = get_storage_class()()
return media_storage.url(name=file_name)
Django 不会在 DB 中存储完整的 URL。 它在代码级别构建绝对 url。 引用自文档:
将存储在数据库中的所有内容都是文件的路径(相对于 MEDIA_ROOT)。
您可以使用build_absolute_uri()
方法获取文件的完整 URL。 例如,您可以在序列化程序级别执行此操作:
class YourSerializer(ModelSerializer):
preferred_profile_photo = serializers.SerializerMethodField()
class Meta:
model = YourModel
fields = [
'preferred_profile_photo',
]
def get_preferred_profile_photo(self, obj):
request = self.context.get('request')
return request.build_absolute_uri(obj.preferred_profile_photo)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.