将django ImageField与Tastypie一起使用

时间:2016-03-26 20:27:39

标签: python django django-models tastypie

我正在尝试将图像存储在我的后端,我可以使用ImageField引用,以便能够通过爆头链接用户。关于如何在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))
]
  • 我的媒体文件夹位于我的项目目录中(与settings.py相同)

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

  • api.py在我的django app中(与models.py相同)
  • 网址和模型位于标准的django位置

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

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

或添加博客/ v1 /媒体等的许多其他组合。我无法通过浏览器或html页面看到图像。

有谁知道我错过了什么?我很难找到有关如何在tastypie

中执行此操作的文档

3 个答案:

答案 0 :(得分:1)

您没有提供错误的详细信息,因此我只能猜测错误!所以如果您提供更多详细信息,我会在错误时将其删除!
也许问题是你没有在settings.py文件中设置MEDIA_ROOT,如下所示:

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

答案 1 :(得分:1)

这可能是你的问题:

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

除非该文件已存储在您的存储空间中,否则它实际上不会引用您的文件。

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

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

答案 2 :(得分:1)

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

我不得不改变: 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

我将MEDIA_ROOT添加到设置中,因为Iman建议 settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR + '/media/'  # Added this

当我创建User对象时,我从Sean(这是必需的)获取建议,在创建User对象时将文件对象包装在django文件类中。 I used the image class这是django文件类的瘦包装。

来自 ./ 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而不是媒体更合适,因为我将内容直接放在后端。媒体意味着更多地处理我发现的用户上传。既然这是我未来的意图,我就是这样离开的。