2015-11-30 10 views
8

私は各ユーザーが1つのブログ投稿に複数の画像をアップロードできるようにしようとしています。私は数日間これを行うための最良の方法を試しています。これを行うベストプラクティスは何ですか?djangoのブログ投稿に複数の画像をアップロードするには

私が読んだところでは、ブログ投稿モデルから別のイメージモデルを作成し、外部キーを使用する必要があります。そうですか? その後、同時に複数の写真をアップロードできるようにする方法があります。私はドロップゾーンのようなものを使うべきだと仮定していますか?

写真の保存に関するベストプラクティスについてのアドバイスも歓迎します。私はAmazon S3と曇りを見てきました。スケーラブルなものを作りたい。

ご協力いただければ幸いです。

+0

一つの方法を試してみてください画像のアップロードhttp://koensblog.eu/blog/7/multiple-file-upload-django/またはその他の方法でdjango-ckeditorを使用し、画像アップロードプラグインの1つを使用します。画像はamazon s3ストレージにのみアップロードされますあなたのs3のイメージの場所に適切なアドレスであなたのコンテンツにimgタグが挿入されます –

答えて

18

2つのモデルが必要です。 1つは投稿用、もう1つは画像用です。あなたのイメージモデルは、PostモデルへのForeignKeyを持っているでしょう:

class Post(models.Model): 
    user = models.ForeignKey(User) 
    title = models.CharField(max_length=128) 
    body = models.CharField(max_length=400) 

def get_image_filename(instance, filename): 
    title = instance.post.title 
    slug = slugify(title) 
    return "post_images/%s-%s" % (slug, filename) 



class Images(models.Model): 
    post = models.ForeignKey(Post, default=None) 
    image = models.ImageField(upload_to=get_image_filename, 
           verbose_name='Image',) 

あなたはモデルごとにフォームを作成する必要がありますが、彼らは、ユーザーがフォームのポストに彼を記入したときのように、相互に関連されますポストのためにあまりにも成功裏に掲載する画像形式を完了することがあり、我々は、ビューでそれを行うものとしますが、今のフォームは、今これはすべての最も重要な部分である。この

class PostForm(forms.ModelForm): 
    title = forms.CharField(max_length=128) 
    body = forms.CharField(max_length=245, label="Item Description.") 

    class Meta: 
     model = Post 
     fields = ('title', 'body',) 


class ImageForm(forms.ModelForm): 
    image = forms.ImageField(label='Image')  
    class Meta: 
     model = Images 
     fields = ('image',) 

のようなものを見ることができますこれは複数の画像を1つの魔法にアップロードするためのものです。一度に複数の画像をアップロードできるようにするには、複数の画像フィールドが必要ですか?それはDjango formsetsと恋に落ちる場所です。私たちは、あなたは、私がリンクされているDjangoのドキュメントのフォームセット、読むことができ、これを実現するためにDjangoのフォームセットを定義さ:)しかし、ここであなたのビューは次のようになりべきかであるだろう:私たちが得ているビューで

@login_required 
def post(request): 

    ImageFormSet = modelformset_factory(Images, 
             form=ImageForm, extra=3) 

    if request.method == 'POST': 

     postForm = PostForm(request.POST) 
     formset = ImageFormSet(request.POST, request.FILES, 
           queryset=Images.objects.none()) 


     if postForm.is_valid() and formset.is_valid(): 



      post_form = postForm.save(commit=False) 
      post_form.user = request.user 
      post_form.save() 

      for form in formset.cleaned_data: 
       image = form['image'] 
       photo = Images(post=post_form, image=image) 
       photo.save() 
      messages.success(request, 
          "Yeeew,check it out on the home page!") 
      return HttpResponseRedirect("/") 
     else: 
      print postForm.errors, formset.errors 
    else: 
     postForm = PostForm() 
     formset = ImageFormSet(queryset=Images.objects.none()) 
    return render(request, 'index.html', 
        {'postForm': postForm, 'formset': formset}, 
        context_instance=RequestContext(request)) 

両方のフォームが有効であればビューがチェックします。このようにして、ユーザーはフォームに記入し、すべての画像をアップロードする必要があります。この画像は3 extra=3です。その後、投稿は正常に作成されます。

あなたのテンプレートは、次のようになります。

<form id="post_form" method="post" action="" 
     enctype="multipart/form-data"> 

    {% csrf_token %} 
    {% for hidden in postForm.hidden_fields %} 
     {{ hidden }} 
    {% endfor %} 

    {% for field in postForm %} 
     {{ field }} <br /> 
    {% endfor %} 

    {{ formset.management_form }} 
    {% for form in formset %} 
     {{ form }} 
    {% endfor %} 


    <input type="submit" name="submit" value="Submit" /> 
</form> 
+0

ありがとうこれほど多く! dropzone jsのようなドラッグ・アンド・ドロップ・システムを組み込む方法は?ドラッグ&ドロップ方式が必要な場合は、書式セットが必要ですか? – ollysmall

+0

@ollysmall申し訳ありませんが、私はそれを助けることができません、私はJavascriptに気づいていないので、あなたはそれをどうやってやるか教えてくれません。しかし、これをチェックしてくださいhttps://github.com/sigurdga/django-jquery-file-upload私はあなたが求めているものを正確にしようとしたと私はdjango jqueryファイルのアップロードを見つけましたが、私はそれをどのように遊ぶかわからなかったそれがformsetsで動作するためです。おそらくそれを試してみてください? – qasimalbaqali

+0

@ qasimalbaqali私はパーティーに遅刻していますが、ここでは若干異なる問題があります。[私の質問](https://stackoverflow.com/questions/44159559/need-to-have-a-required-and-optional- fields-in-django-formset)はここにあります。 – dungu

-4

をあなたには、いくつかの入力名を持っている場合= image1の名前=画像2名=画像3など、あなたのテンプレートに複数の追加のこの

for i in xrange(1,4): 
     if ('image'+str(i)) in request.FILES: 
      image = request.FILES.get('image'+str(i), None) 
      if image.content_type == 'image/jpeg' 
       image._set_name(str(description.id)+'_image'+str(i)+'.jpg') 
       photo = Images(description=description, image=image) 
       photo.save() 
関連する問題