英文:
How can I allow users to upload multiple images and files in django?
问题
我想创建类似Facebook/Twitter的创建帖子功能。我有一个类似于example.com/username/posts/create
的网址,其中包含与帖子模型相关的表单。正如您可能知道的,标准的ImageField和FileField没有上传多个项目的功能,也没有像拖放这样的良好编辑器。拖放并不是关键功能,但我真的想以某种方式处理类似Twitter/Facebook的编辑器,带有方便的按钮来上传照片/视频/文件。
我看到有很多自定义编辑器,如DJANGO-CKEDITOR等,但我不明白它们如何与一个图像/文件字段一起工作。也许有人曾经面对过这个问题?
以下是我表单和模型,如果有帮助的话:
Models.py
class Post(models.Model):
title = models.CharField(max_length=200, null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
images = models.ImageField(null=True, blank=True, upload_to="posts/images")
body = models.TextField(max_length=255)
post_date = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
likes = models.ManyToManyField(User, through='UserPostRel', related_name='likes')
forms.py
class PostCreationForm(ModelForm):
class Meta:
model = Post
fields = [
'title',
'body',
'images',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['title'].label = "Title"
self.fields['body'].label = "Body"
self.fields['images'].label = "Images"
希望这对您有所帮助。
英文:
I want to create functionality like facebook/twitter for creating a post. I have a url smth like example.com/username/posts/create
with the form related to the post model. As you probably know, there is no ability in vanilla ImageField & FileField to upload multiple items, as well as no decent editor for drag&drop like things. Drag&Drop isn't a crucial feature, but I really want to handle with a twitter/facebook like editor somehow. With all it's convenient buttons for photo/video/file.
I saw there is a bunch of custom editors like DJANGO-CKEDITOR and etc., but I don't understand how it suppose to work anyway with one image/file field. Maybe, somebody was facing the problem?
Attach my form and model in case it will help:
Models.py
class Post(models.Model):
title = models.CharField(max_length=200, null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
images = models.ImageField(null=True, blank=True, upload_to="posts/images")
body = models.TextField(max_length=255)
post_date = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
likes = models.ManyToManyField(User, through='UserPostRel', related_name='likes')
forms.py
class PostCreationForm(ModelForm):
class Meta:
model = Post
fields = [
'title',
'body',
'images',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['title'].label = "Title"
self.fields['body'].label = "Body"
self.fields['images '].label = "images"
答案1
得分: 3
通常,这是通过额外的模型完成的:
class Post(models.Model):
title = models.CharField(max_length=200, null=True, blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
body = models.TextField(max_length=255)
post_date = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
likes = models.ManyToManyField(
settings.AUTH_USER_MODEL, through='UserPostRel', related_name='likers'
)
class PostImage(models.Model):
post = models.ForeignKey(Post, related_name='images')
image = models.ImageField(upload_to='posts/images')
然后,我们创建一个小表单来处理批量上传:
class PostForm(forms.ModelForm):
files = forms.FileField(
label='',
required=False,
widget=forms.ClearableFileInput(attrs={'multiple': True}),
)
class Meta:
model = Post
fields = [
'title',
'body',
]
labels = {'title': 'Title', 'body': 'Body'}
def _save_m2m(self):
super()._save_m2m()
images = [
PostImage(post=self.instance, image=file)
for file in self.files.get('files')
]
PostImage.objects.bulk_create(images)
然后,在视图中,我们让表单处理这个操作:
from django.shortcuts import redirect, render
def my_view(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form is_valid():
form.save()
return redirect('<i>name-of-some-view</i>')
else:
form = PostForm()
return render(request, '<i>name-of-some-template.html</i>', {'form': form})
注意:通常更好地使用
settings.AUTH_USER_MODEL
来引用用户模型,而不是直接使用User
模型。有关更多信息,您可以查看文档中的 引用User
模型 部分。
英文:
Usually this is done through an extra model:
<pre><code>class Post(models.Model):
title = models.CharField(max_length=200, null=True, blank=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
body = models.TextField(max_length=255)
post_date = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
likes = models.ManyToManyField(
settings.AUTH_USER_MODEL, through='UserPostRel', related_name='likers'
)
class PostImage(models.Model):
post = models.ForeignKey(Post, related_name='images')
image = models.ImageField(upload_to='posts/images')</code></pre>
Then we make a small form to handle the bulk upload:
<pre><code>class PostForm(forms.ModelForm):
files = forms.FileField(
label='',
required=False,
widget=forms.ClearableFileInput(attrs={'multiple': True}),
)
class Meta:
model = Post
fields = [
'title',
'body',
]
labels = {'title': 'Title', 'body': 'Body'}
def _save_m2m(self):
super()._save_m2m()
images = [
PostImage(post=self.instance, image=file)
for file in self.files.get('files')
]
PostImage.objects.bulk_create(images)</code></pre>
Then in the view we let the form handle this:
<pre><code>from django.shortcuts import redirect, render
def my_view(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('<i>name-of-some-view</i>')
else:
form = PostForm()
return render(request, '<i>name-of-some-template.html</i>', {'form': form})</code></pre>
> Note: It is normally better to make use of the settings.AUTH_USER_MODEL
<sup>[Django-doc]</sup> to refer to the user model, than to use the User
model <sup>[Django-doc]</sup> directly. For more information you can see the referencing the User
model section of the documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论