我正在开发个人博客的后端,并使用this tutorial作为日期和时间,以创建用于创建博客文章的表单。
即使我选择一个或多个标签,也不会将其添加到帖子中。使用此表单发布后的帖子没有标签。但是,如果我通过django admin做同样的事情,我将无法创建没有标签的帖子。
create_post.html
<form class="" method="POST" enctype="multipart/form-data" novalidate>{% csrf_token %}
<div class="form-group">
<div class="row">
<div class="col-sm-9">
<div class="form-group mb-4">
<div>{{ form.title }}</div>
<label for="id_title">
<span class="text-info" data-toggle="tooltip" title="{{ form.title.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.title.errors }}</small>
</label>
</div>
<div class="form-group mb-4">
<div>{{ form.description }}</div>
<label for="id_description">
<span class="text-info" data-toggle="tooltip" data-placement="bottom" title="{{ form.description.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.description.errors }}</small>
</label>
</div>
<div class="form-group mb-4">
<div>{{ form.contents }}</div>
<label for="id_contents">
<span class="text-info" data-toggle="tooltip" data-placement="bottom" title="{{ form.contents.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.contents.errors }}</small>
</label>
</div>
<div class="form-group mb-4">
<div>{{ form.header_image_link }}</div>
<label for="id_header_image">
<span class="text-info" data-toggle="tooltip" title="{{ form.header_image_link.help_text|safe }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.header_image_link.errors }}</small>
</label>
</div>
</div>
<div class="col-sm-3">
<div class="form-group mb-4">
<div class=""><h4>{{ form.post_category.label }}</h4></div>
<div>{{ form.post_category }}</div>
<label for="id_category">
<span class="text-info" data-toggle="tooltip" title="{{ form.post_category.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.post_category.errors }}</small>
</label>
</div>
<div class="form-group mb-4">
<div class=""><h4>{{ form.post_tag.label }}</h4></div>
<div>{{ form.post_tag }}</div>
<label for="id_tag">
<span class="text-info" data-toggle="tooltip" title="{{ form.post_tag.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.post_tag.errors }}</small>
</label>
</div>
<div class="form-inline mb-4 py-0">
<div class="input-group mx-1">
<label for="id_highlighted">{{ form.highlighted.label }}</label>
<div class="ml-1">{{ form.highlighted }}</div>
</div>
<div class="input-group mx-1">
<label for="id_draft">{{ form.draft.label }}</label>
<div class="ml-1">{{ form.draft }}</div>
</div>
</div>
<div class="form-group mb-4">
<div class=""><h4>{{ form.publishing_date.label }}</h4></div>
<div class="input-group date" data-target-input="nearest">
{{ form.publishing_date }}
<div class="input-group-append" data-target="#publishing_date_field" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
<label for="publishing_date_field">
<span class="text-info" data-toggle="tooltip" title="{{ form.publishing_date.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.publishing_date.errors }}</small>
</label>
<script>
$(function () {
$("#publishing_date_field").datetimepicker({
format: 'DD/MM/YYYY HH:mm',
});
});
</script>
</div>
<div class="form-group mb-4">
<div class=""><h4>{{ form.author.label }}</h4></div>
<div>{{ form.author }}</div>
<label for="id_author">
<span class="text-info" data-toggle="tooltip" title="{{ form.author.help_text }}">
<i class="far fa-question-circle"></i>
</span>
<small class="text-danger">{{ form.author.errors }}</small>
</label>
</div>
</div>
</div>
</div>
<hr>
<div class="row justify-content-md-center">
<div class="col-md-auto">
<input type="submit" class="btn btn-info shadow" value="Pubblica">
</div>
</div>
</form>
forms.py
class BlogPostForm(forms.ModelForm):
title = forms.CharField(
max_length=70,
help_text="<small>Write post title here. The title must be have max 70 characters.</small>",
widget=forms.TextInput(
attrs={
"placeholder": "Titolo",
"type": "text",
"id": "id_title",
"class": "form-control form-control-lg",
}
),
)
description = forms.CharField(
max_length=200,
help_text="<small>Write a post short description here. The description must be have max 200 characters.</small>",
widget=forms.Textarea(
attrs={
"placeholder": "Descrizione",
"type": "text",
"id": "id_description",
"class": "form-control",
"rows": "2",
}
),
)
contents = forms.CharField(
help_text="<small>Write your contents here.</small>",
widget=forms.Textarea(
attrs={
"placeholder": "Contenuti",
"type": "text",
"id": "id_contents",
"class": "form-control",
"rows": "20",
}
),
)
publishing_date = forms.DateTimeField(
input_formats=['%d/%m/%Y %H:%M'],
label="Data di pubblicazione",
help_text="<small>Write data and hour of publication. You can use also a past or a future date.</small>",
widget=forms.DateTimeInput(
attrs={
"id": "publishing_date_field",
'class': 'form-control datetimepicker-input',
'data-target': '#publishing_date_field',
}
),
)
draft = forms.BooleanField(
label="Bozza",
widget=forms.CheckboxInput(
attrs={
"type": "checkbox",
"id": "id_draft",
"class": "form-check-input mx-2",
}
),
required=False,
)
author = forms.ModelChoiceField(
label="Autore",
help_text="<small>Select the author.</small>",
widget= forms.Select(
attrs={
"id": "id_author",
"class": "custom-select",
}
),
empty_label=" ",
queryset= User.objects.all(),
)
post_tag =forms.ModelMultipleChoiceField(
label="Tag",
help_text="<small>Select one or more tags. Press CTRL and click on a tag for multiple selection.</small>",
widget= forms.SelectMultiple(
attrs={
"id": "id_category",
"class": "custom-select",
"size": "4",
}
),
queryset= BlogTag.objects.all(),
)
post_category = forms.ModelChoiceField(
label="Categoria",
help_text="<small>Select a category.</small>",
widget= forms.Select(
attrs={
"id": "id_category",
"class": "custom-select",
}
),
empty_label=" ",
queryset= BlogCategory.objects.all(),
)
header_image_link = forms.CharField(
max_length=1000,
help_text="<small>Past here the image link.</small>",
widget=forms.TextInput(
attrs={
"placeholder": "Url dell'immagine di testata",
"type": "text",
"id": "id_header_image",
"class": "form-control",
}
)
)
highlighted = forms.BooleanField(
label="In evidenza",
widget=forms.CheckboxInput(
attrs={
"type": "checkbox",
"id": "id_highlighted",
"class": "form-check-input mx-2",
}
),
required=False,
)
class Meta:
model = BlogPost
fields = [
"author",
"title",
"description",
"contents",
"header_image_link",
"post_tag",
"post_category",
"highlighted",
"draft",
"publishing_date",
]
models.py
class BlogPost(models.Model):
publishing_date = models.DateTimeField(
default=timezone.now,
blank=True,
)
updating_date = models.DateTimeField(
auto_now=True,
)
timestamp = models.DateTimeField(
auto_now=False,
auto_now_add=True,
)
title = models.CharField(
max_length=70,
unique=True,
)
slug_post = models.SlugField(
max_length=70,
unique=True,
)
description = models.TextField(
max_length=200,
blank=True,
)
contents = models.TextField(
blank=True,
)
draft = models.BooleanField(
default=False,
)
author = models.ForeignKey(
User,
related_name = "author_blogpost",
on_delete=models.CASCADE,
)
highlighted = models.BooleanField(
default=False,
)
header_image_link = models.CharField(
max_length=1000,
)
post_category = models.ForeignKey(
BlogCategory,
related_name = "category_blogpost",
on_delete=models.CASCADE,
)
post_tag = models.ManyToManyField(
BlogTag,
related_name = "tag_blogpost",
)
def __str__(self):
return self.title
class Meta:
ordering = ['-publishing_date']
views.py
def createPost(request):
if request.method == "POST":
form = BlogPostForm(request.POST or None)
if form.is_valid():
new_post = form.save(commit=False)
new_post.slug_post = slugify(new_post.title)
new_post.save()
return redirect('blogpost_list')
else:
form = BlogPostForm()
context = {
'form': form,
}
template = 'blog/editing/create_post.html'
return render(request, template, context)
def updatePost(request, slug_post=None):
update_post = get_object_or_404(BlogPost, slug_post=slug_post)
form = BlogPostForm(request.POST or None, instance=update_post)
if form.is_valid():
update_post = form.save(commit=False)
update_post.slug_post = slugify(update_post.title)
update_post.save()
return redirect('blogpost_list')
context = {
'form': form,
}
template = 'blog/editing/create_post.html'
return render(request, template, context)
我怎么了?
答案 0 :(得分:1)
许多关系必须手动设置。您可以覆盖ModelForm的save方法,这意味着您永远不能使用“ commit = False”
def save(self, commit=True):
if not commit:
raise Exception('Cannot save many to many fields if the blog post is not committed')
instance = super().save()
instance.post_tag.add(*self.cleaned_data['post_tag'])
return instance
或者您可以在视图中添加标签
if form.is_valid():
update_post = form.save(commit=False)
update_post.slug_post = slugify(update_post.title)
update_post.save()
update_post.post_tag.add(*form.cleaned_data['post_tag'])
return redirect('blogpost_list')