2017-06-19 6 views
0

私は、必須ではないイメージを受け入れるモデルを持っています。djangoモデルで静的なデフォルトイメージの完全なURLを取得する方法

私はデフォルトのイメージへのリンクを提供しようとしているので、後でユーザーがモデルをリクエストしたときにデフォルトのイメージを送信できます。

私はDRFを使用しているため、必ずしもビュー内にreverseへのアクセス権がありません。 based on this response私はモデル自体の機能を達成しようとしています。

# models.py 
class Widget(models.Model): 
...  
    def image_url(self): 

     ''' 
     Returns the url of the image for the model instance. 

     If no image is found, return the path to the default meal image. 
     ''' 
     if self.image and hasattr(self.image, 'url'): 
      return self.image.url 
     else: 
      return settings.STATIC_URL + 'img/default/meal.png' 

そして、私のシリアライザに私は、フィールドの代わりに、画像を追加:

#serializers.py 
class WidgetSerializer(serializers.HyperlinkedModelSerializer): 
... 
    class Meta: 
     model = Widget 
     fields = ('image_url', 
     ... 
     ) 

をしかし、もちろんこれは私だけの画像、/static/img/default/meal.png代わりのhttp://localhost:8010/static/img/default/meal.pngのようなものの相対パスを提供します。

私は完全なURLで対応できるように、モデル内のURLのベース名を取得するにはどうすればよいですか?これは正しいアプローチですか?

また、私のブラウザではちょうどhttp://localhost:8010/static/img/default/meal.pngを訪問しましたが、画像が見つかりませんでした。これについてのアイデアもありますか?

--EDIT--

私は一種の観点から、この作業を取得する方法を考え出しました。今のところ、詳細ビューでのみ機能し、同じコードをリストビューにコピーしてDRYのためにやるのが嫌な作業をする必要があります。

シリアライザでデフォルト画像の完全なURLを取得するのが理想的ですが、依然としてリクエストオブジェクトにアクセスする方法がわかりません。

# views.py 
class WidgetDetail(APIView): 

    def get_object(self, pk): 
     try: 
      return Widget.objects.get(pk=pk) 
     except Widget.DoesNotExist: 
      raise Http404 

    def get(self, request, pk, format=None): 
     widget = self.get_object(pk) 
     serializer = WidgetSerializer(
      widget, 
      context={'request': request}, 
     ) 
     serialized_data = serializer.data 

     if not widget.image: 
      serialized_data['image'] = request.build_absolute_uri(
       settings.STATIC_URL + 'img/default/widget.png') 
      # print(serialized_data['image']) 

     return Response(serialized_data) 
... 

class WidgetList(APIView): 

    def get(self, request, format=None): 
     widgets = Widget.objects.all() 
     serializer = WidgetSerializer(
      widgets, 
      many=True, 
      context={'request': request}, 
     ) 
     #... Would need to replace null urls here.... 
     return Response(serializer.data) 

ただし、シリアライザにコンテキストを渡しているため、そこにアクセスできるはずです。

答えて

2

view.py:

data = WidgetSerializer(wight, context={'request': request}).data 

serializer.py

class WidgetSerializer(serializers.HyperlinkedModelSerializer): 
... 
    class Meta: 
     model = Widget 
     fields = ('image', 
     ... 
     ) 

があなたのシリアライザにcontext={'request': request}を追加するには、あなたのimage.more情報hereのフルパスを取得します。


あなたはシリアライザでそれを設定する場合:

class WidgetSerializer(serializers.HyperlinkedModelSerializer): 
    image = serializers.SerializerMethodField() 
    class Meta: 
     model = Widget 
     fields = ('image', 
     ... 
     ) 

    def get_image(self, instance): 
     request = self.context.get('request') 
     return request.build_absolute_uri(instance.get_image()) 

model.py

class Widget(models.Model): 
...  
    def get_image(self): 
     if self.image: 
      return self.image.url 
     else: 
      return settings.STATIC_URL + 'img/default/meal.png' 
+0

を、どのように私はシリアライザの内部でコンテキストを得るのですか?シリアライザ内で 'context = self.context'を実行しようとしていますが、' self'が定義されていないために動作しません.... – sonarforte

+0

'data = WidgetSerializer(wight、context = {'request':request}))data 'はシリアライザの中であなたのview.pyにありません – Ykh

+0

ああ、私はビュー内のデータを取得し、正しいものでimage_urlを置き換えてから、ビューを続行することをお勧めしますか? – sonarforte

関連する問題