将 django ImageField 与 Tastypie 一起使用

Using django ImageField with Tastypie

我正在尝试在我的后端存储图像,我可以使用 ImageField 引用这些图像,以便 link 用户可以使用头像。我没有找到关于如何在 TastyPie 中执行此操作的文档。

要从我的后端获取显示在 html 网页上的图像,我需要采取哪些最少的可行步骤?

这是我一直在尝试的代码:

models.py

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    headshot = models.ImageField()

settings.py

MEDIA_URL = '/media/'

api.py

from tastypie.resources import ModelResource
from tastypie import fields
from blog.models import User

class UserResource(ModelResource):
    headshot = fields.FileField(attribute='headshot', null=True, blank=True)

    class Meta:
        queryset = User.objects.all()
        resource_name = 'users'

urls.py

from django.conf.urls import include, url
from django.contrib import admin

from tastypie.api import Api

from blog.api import UserResource

blog = Api(api_name='v1')
blog.register(UserResource())

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^blog/', include(blog.urls))
]

测试图片位置--> /myproject/media/images/nickbrady.jpg

我这样创建了我的用户对象:

User.objects.create(name='Nick Brady', headshot='images/nickbrady.jpg')

我目前的 API 回复是这样的:

{
  "meta": {
    "limit": 20,
    "next": null,
    "offset": 0,
    "previous": null,
    "total_count": 1
  },
  "objects": [
    {
      "headshot": "/media/images/nickbrady.jpg",
      "id": 1,
      "img": null,
      "name": "Nick Brady",
      "resource_uri": "/blog/v1/users/1/"
    }
  ]
}

当我试图去

http://127.0.0.1:8000/media/images/nickbrady.jpg

或添加 blog/v1/media 等的许多其他组合。我无法通过浏览器或 html 页面查看图像。

有人知道我错过了什么吗?我很难在 tastypie

中找到有关如何执行此操作的文档

你没有提供错误的详细信息,所以我只能猜测哪里出了问题!所以如果你提供更多详细信息,如果有错我会删除它!
也许问题是您没有像下面这样在 settings.py 文件中设置 MEDIA_ROOT

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

这可能是你的问题:

User.objects.create(name='Nick Brady', headshot='images/nickbrady.jpg')

除非该文件已经在您存储中的那个位置,否则它实际上不会引用您的文件。

您可能希望在此 class 中包装一个文件对象并保存它而不是字符串:https://docs.djangoproject.com/en/1.9/ref/files/file/

保存后,该文件将被复制到您的存储目录。

好的,所以我在其他两个答案的帮助下深入研究了文档,并找到了解决方案。

我不得不改变: urls.py 至:

from django.conf.urls import include, url
from django.conf.urls.static import static  # Added this line
from django.contrib import admin

from tastypie.api import Api

from blog.api import UserResource

blog = Api(api_name='v1')
blog.register(UserResource())

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^blog/', include(blog.urls))
]  + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)  # And this

我按照 Iman 向 settings.py:

的建议在设置中添加了 MEDIA_ROOT
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR + '/media/'  # Added this

当我创建我的用户对象时,我听取了 Sean 的建议(这是必需的),在创建我的用户对象时将文件对象包装在 django 文件中 class。 I used the image class 这是 django 文件 class.

上的薄包装

来自 ./manage.py shell 它看起来像这样。

>>> from django.core.files.images import ImageFile
>>> img_file = open('path/to/file.jpg', 'rb')  # 'rb' --> read as bytes since image
>>> django_wrapped_img = ImageFile(img_file)
>>> User.objects.create(name='Nick Brady', headshot=django_wrapped_img)

以这种方式创建对象后,图像被复制到指定我的 MEDIA_ROOT 的位置。

完成此操作后,我能够成功地从 Postman 看到我的图像。

注意:在这一点上,使用 static_url 和 root 比使用媒体更合适,因为我将我的内容直接放到后端。我发现媒体更多是为了处理用户上传。因为这是我未来的打算,所以我就这样离开了。