输出 (image_url字段中缺少端口“:1337”)
{ "count": 1, "next": null, "previous": null, "results": [ { "id": 1, "user": 1, "title": "Post 1", "slug": "post1", "image_url": "http://0.0.0.0/mediafiles/publisher/sample-image4.jpg", "content": "First", "draft": false, "publish": "2019-04-26", "updated": "2019-04-26T22:28:35.034742Z", "timestamp": "2019-04-26T22:28:35.034795Z" } ] }
除非包含以下端口,否则“ image_url”字段将无法正确链接:
"image_url": "http://0.0.0.0:1337/mediafiles/publisher/sample-image4.jpg",
堆:
我正在使用Django REST框架返回序列化对象的列表。这些对象包含一个名为“ image”的FileField,我可以输出该图像的URL。唯一的事情是,当我单击浏览器输出中的链接时,如果不手动在以下地址中添加服务器端口,则无法访问资源
http://0.0.0.0:1337/mediafiles/publisher/sample-image4.jpg
我不确定这是nginx问题,Django设置问题还是我的代码配置方式。我在通过Google查找其他报告的案例时遇到了麻烦(可能是因为我还是Django的新手,尽管遵循了教程,但不确定正确的配置)。
我尝试了其中一些解决方案,但它们不输出端口。
有这个问题,但是我没有使用ImageField,而是想找到一种解决方案,以解决使用FileField的情况。对主要问题的评论表明,也不需要添加端口,所以也许这是一个基础问题,而不是Django问题?对此的指导将是很棒的。
models.py
class Post(models.Model): class Meta: ordering = ('timestamp',) user = models.ForeignKey(User, on_delete=models.PROTECT) title = models.CharField(max_length=120) slug = models.SlugField(unique=True) image = models.FileField(upload_to='publisher/', null=True, blank=True) content = models.TextField() draft = models.BooleanField(default=False) publish = models.DateField(auto_now=False, auto_now_add=False) updated = models.DateTimeField(auto_now=True, auto_now_add=False) timestamp = models.DateTimeField(auto_now=False, auto_now_add=True) def __str__(self): return self.title def __unicode__(self): return str(self.id) def get_absolute_url(self): return reverse("post:detail", kwargs={"slug":self.slug})
serializers.py
class PostSerializer(serializers.ModelSerializer): image_url = serializers.SerializerMethodField() class Meta: model = Post fields = [ 'id', 'user', 'title', 'slug', 'image_url', 'content', 'draft', 'publish', 'updated', 'timestamp', ] def get_image_url(self, post): request = self.context.get('request') if post.image and hasattr(post.image, 'url'): image_url = post.image.url return request.build_absolute_uri(image_url) else: return None
urls.py
urlpatterns = [ path('admin/', admin.site.urls), re_path('blog/(?P<version>(v1|v2))/', include('blog.urls')) ] ... [ url(r'^posts/$', PostListAPIView.as_view(), name='posts'), ] if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
class PostListAPIView(generics.ListAPIView): model = Post queryset = Post.objects.all() serializer_class = PostSerializer
docker-compose.yml
version: '3.7' services: web: build: ./app command: gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000 volumes: - ./app/:/usr/src/app/ - static_volume:/usr/src/app/staticfiles - media_volume:/usr/src/app/mediafiles ports: - "8000" env_file: ./app/.env environment: - DB_ENGINE=django.db.backends.postgresql - DB_USER - DB_PASSWORD - DB_HOST=db - DB_PORT=5432 - DATABASE=postgres depends_on: - db networks: - backend db: image: postgres:10.7-alpine ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data/ networks: - backend nginx: build: ./nginx volumes: - static_volume:/usr/src/app/staticfiles - media_volume:/usr/src/app/mediafiles ports: - "1337:80" depends_on: - web networks: - backend networks: backend: driver: bridge volumes: postgres_data: static_volume: media_volume:
nginx.conf
upstream hello_django { server web:8000; } server { listen 80; location / { proxy_pass http://hello_django; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; } location /staticfiles/ { alias /usr/src/app/staticfiles/; } location /mediafiles/ { alias /usr/src/app/mediafiles/; } location /favicon.ico { access_log off; log_not_found off; } }
由于这个问题,我终于找到了解决图像URL的方法,这个问题稍有不同。
解决方案1
将端口号添加到nginx配置中的Host标头中,如下所示:
location / { proxy_pass http://hello_django; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host:1337; <<------- HERE proxy_redirect off; }
解决方案2
将nginx配置中的Host标头更改http_host如下:
http_host
location / { proxy_pass http://hello_django; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; <<------- HERE proxy_redirect off; }
无论哪种情况,DURL(图像链接)现在都按以下方式返回图像URL 。
HTTP 200 OK Allow: GET, HEAD, OPTIONS Content-Type: application/json Vary: Accept { "count": 1, "next": null, "previous": null, "results": [ { "id": 2, "user": 1, "title": "First post", "slug": "first", "image_url": "http://0.0.0.0:1337/mediafiles/publisher/background.gif", <----HERE "content": "Second post content.", "draft": false, "publish": "2019-05-22", "updated": "2019-05-22T09:41:36.257605Z", "timestamp": "2019-05-22T07:58:01.471534Z" } ] }