如何使 Django 表单中的实例具有多个值?
How to make the instance inside Django form take multiple values?
我正在制作一个 Django 博客,我想让用户编辑他的 post。我有 2 个表单要呈现,Post 包含(标题、post 图像、内容、类别)的表单和包含(标签名称)的 post 标签的另一个单独表单。要编辑标签,我必须获取与 post 相关的所有标签并将它们设置为 instance
属性,该属性只需要一个 object (我有多个标签用于一个 post).
这是我的模型:
class PostTags(models.Model):
tag_name = models.CharField(max_length=100)
def __str__(self):
return self.tag_name
class Post(models.Model):
title = models.CharField(max_length=50)
picture = models.ImageField(null=True,upload_to='images/')
content = models.CharField(max_length=255)
likes = models.ManyToManyField(User,blank=True,related_name='likes')
dislikes = models.ManyToManyField(User,blank=True,related_name='dislikes')
date_of_publish = models.DateTimeField(auto_now_add=True,null=True,blank=True)
user = models.ForeignKey(User,on_delete=models.CASCADE)
category = models.ForeignKey(Category,on_delete=models.CASCADE)
tag = models.ManyToManyField(PostTags,blank=True)
def __str__(self):
return self.title
这是我的表格:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','picture','content','category']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'picture': forms.FileInput(attrs={'class': 'form-control'}),
'content':forms.TextInput(attrs={'class': 'form-control'}),
'category' : forms.Select(attrs={'class':'form-control'}),
}
class TagsForm(forms.ModelForm):
class Meta:
model = PostTags
fields = ['tag_name']
widgets = {
'tag_name': forms.TextInput(attrs={'class': 'form-control', 'data-role': 'tagsinput'})
}
这是我尝试获取 views.py
中标签形式的所有标签
def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
# tagInstance = []
for tag in post.tag.all():
print(tag)
newTag = PostTags.objects.get(tag_name=tag)
tag_form = TagsForm(instance=newTag)
# tagInstance.append(newTag)
# print(tagInstance)
# if request.method == 'POST':
# form = PostForm(request.POST,instance=post)
# if form.is_valid():
# form.save()
# return redirect('post')
context = {"post_form":post_form,'tag_form':tag_form}
return render (request,"dj_admin/editpost.html",context)
以上尝试仅导致最后一个标签呈现为预期的标签形式
如果我没理解错的话,您想要在模板中呈现与 post 相关的所有 tag_forms。
您可以使用 django model inline_formsets
实现您想要的效果
forms.py:
from django.forms import inlineformset_factory
from .models import Post, PostTags
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','picture','content','category']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'picture': forms.FileInput(attrs={'class': 'form-control'}),
'content':forms.TextInput(attrs={'class': 'form-control'}),
'category' : forms.Select(attrs={'class':'form-control'}),
}
class TagsForm(forms.ModelForm):
class Meta:
model = PostTags
fields = ['tag_name']
widgets = {
'tag_name': forms.TextInput(attrs={'class': 'form-control', 'data-role': 'tagsinput'})
}
TagFormSet = inlineformset_factory(PostTags, Post, fields=('tag_name',))
views.py:
from .forms import PostForm, TagsForm, TagFormSet
def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
tag_formset = TagFormSet(instance=post)
if request.method == 'POST':
form = PostForm(request.POST, instance=post)
tag_formset = TagFormSet(request.POST, instance=post)
if form.is_valid() and tag_formset.is_valid():
form.save()
tag_formset.save()
return redirect('post')
context = {'post_form': post_form, 'tag_formset': tag_formset}
return render (request, 'dj_admin/editpost.html', context)
然后在模板文件中,您可以像这样简单地添加 {{ tag_formset }}
:
<form method="post">
{{ formset }}
</form>
可能有更简洁的解决方案,但这应该有效:
def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
context = {}
context['post_form'] = post_form
count = 0
for tag in post.tag.all():
print(tag)
newTag = PostTags.objects.get(tag_name=tag)
tag_form = TagsForm(instance=newTag)
count += 1
context['tag_form'+str(count)] = TagsForm(instance=newTag)
context['tag_form_counter'] = count
return render (request,"dj_admin/editpost.html",context)
因此,在您的模板中,您必须检查 tag_form_counter 变量以了解您有多少 tag_forms。并制作一个 forloop 来展示它们。
我正在制作一个 Django 博客,我想让用户编辑他的 post。我有 2 个表单要呈现,Post 包含(标题、post 图像、内容、类别)的表单和包含(标签名称)的 post 标签的另一个单独表单。要编辑标签,我必须获取与 post 相关的所有标签并将它们设置为 instance
属性,该属性只需要一个 object (我有多个标签用于一个 post).
这是我的模型:
class PostTags(models.Model):
tag_name = models.CharField(max_length=100)
def __str__(self):
return self.tag_name
class Post(models.Model):
title = models.CharField(max_length=50)
picture = models.ImageField(null=True,upload_to='images/')
content = models.CharField(max_length=255)
likes = models.ManyToManyField(User,blank=True,related_name='likes')
dislikes = models.ManyToManyField(User,blank=True,related_name='dislikes')
date_of_publish = models.DateTimeField(auto_now_add=True,null=True,blank=True)
user = models.ForeignKey(User,on_delete=models.CASCADE)
category = models.ForeignKey(Category,on_delete=models.CASCADE)
tag = models.ManyToManyField(PostTags,blank=True)
def __str__(self):
return self.title
这是我的表格:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','picture','content','category']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'picture': forms.FileInput(attrs={'class': 'form-control'}),
'content':forms.TextInput(attrs={'class': 'form-control'}),
'category' : forms.Select(attrs={'class':'form-control'}),
}
class TagsForm(forms.ModelForm):
class Meta:
model = PostTags
fields = ['tag_name']
widgets = {
'tag_name': forms.TextInput(attrs={'class': 'form-control', 'data-role': 'tagsinput'})
}
这是我尝试获取 views.py
中标签形式的所有标签def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
# tagInstance = []
for tag in post.tag.all():
print(tag)
newTag = PostTags.objects.get(tag_name=tag)
tag_form = TagsForm(instance=newTag)
# tagInstance.append(newTag)
# print(tagInstance)
# if request.method == 'POST':
# form = PostForm(request.POST,instance=post)
# if form.is_valid():
# form.save()
# return redirect('post')
context = {"post_form":post_form,'tag_form':tag_form}
return render (request,"dj_admin/editpost.html",context)
以上尝试仅导致最后一个标签呈现为预期的标签形式
如果我没理解错的话,您想要在模板中呈现与 post 相关的所有 tag_forms。
您可以使用 django model inline_formsets
实现您想要的效果forms.py:
from django.forms import inlineformset_factory
from .models import Post, PostTags
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','picture','content','category']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'picture': forms.FileInput(attrs={'class': 'form-control'}),
'content':forms.TextInput(attrs={'class': 'form-control'}),
'category' : forms.Select(attrs={'class':'form-control'}),
}
class TagsForm(forms.ModelForm):
class Meta:
model = PostTags
fields = ['tag_name']
widgets = {
'tag_name': forms.TextInput(attrs={'class': 'form-control', 'data-role': 'tagsinput'})
}
TagFormSet = inlineformset_factory(PostTags, Post, fields=('tag_name',))
views.py:
from .forms import PostForm, TagsForm, TagFormSet
def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
tag_formset = TagFormSet(instance=post)
if request.method == 'POST':
form = PostForm(request.POST, instance=post)
tag_formset = TagFormSet(request.POST, instance=post)
if form.is_valid() and tag_formset.is_valid():
form.save()
tag_formset.save()
return redirect('post')
context = {'post_form': post_form, 'tag_formset': tag_formset}
return render (request, 'dj_admin/editpost.html', context)
然后在模板文件中,您可以像这样简单地添加 {{ tag_formset }}
:
<form method="post">
{{ formset }}
</form>
可能有更简洁的解决方案,但这应该有效:
def editPost(request,post_id):
post = Post.objects.get(id= post_id)
post_form = PostForm(instance=post)
context = {}
context['post_form'] = post_form
count = 0
for tag in post.tag.all():
print(tag)
newTag = PostTags.objects.get(tag_name=tag)
tag_form = TagsForm(instance=newTag)
count += 1
context['tag_form'+str(count)] = TagsForm(instance=newTag)
context['tag_form_counter'] = count
return render (request,"dj_admin/editpost.html",context)
因此,在您的模板中,您必须检查 tag_form_counter 变量以了解您有多少 tag_forms。并制作一个 forloop 来展示它们。