Python 使用createview和modelform自动将登录用户设置为django中的作者
我正在构建一个前端表单,允许某人在不访问管理员的情况下发布文章 当用户登录时,我希望他/她能够写一篇文章。保存后,我希望该用户自动设置为文章的作者 我陷入了僵局。任何帮助都将不胜感激 models.pyPython 使用createview和modelform自动将登录用户设置为django中的作者,python,django,django-class-based-views,modelform,inline-formset,Python,Django,Django Class Based Views,Modelform,Inline Formset,我正在构建一个前端表单,允许某人在不访问管理员的情况下发布文章 当用户登录时,我希望他/她能够写一篇文章。保存后,我希望该用户自动设置为文章的作者 我陷入了僵局。任何帮助都将不胜感激 models.py from django.db import models from django.urls import reverse from django.contrib.auth.models import User from django.utils import timezone class
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from django.utils import timezone
class Article(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=65)
text = HTMLField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
class ArticleImage(models.Model):
image = CloudinaryField('image')
image_name = models.CharField(max_length=55,
default='')
article = models.ForeignKey(Article)
def __str__(self):
return self.image_name
class ArticleTag(models.Model):
slug = models.SlugField(max_length=50,
unique=True)
article = models.ForeignKey(Article)
def __str__(self):
return self.slug
class ArticleCategory(models.Model):
slug = models.SlugField(max_length=20,
unique=True)
article = models.ForeignKey(Article)
def __str__(self):
return self.slug
forms.py
class ArticleCreationForm(ModelForm):
class Meta:
model = Article
fields = ['title', 'text']
widgets = {
'title': forms.TextInput(attrs={'placeholder': 'Please add a title. Max: 65 characters'}),
'text': forms.Textarea(attrs={'cols': 80, 'rows': 40, 'placeholder': 'Starting typing your article...'})
}
ArticleImageFormSet = inlineformset_factory(Article, ArticleImage,
fields=('image', 'image_name',),
extra=1,
max_num=1,
widgets={'image_name':
forms.TextInput(attrs={'placeholder': 'Image name'})})
ArticleTagFormSet = inlineformset_factory(Article, ArticleTag,
fields=('slug',),
extra=1,
max_num=1)
ArticleCategoryFormSet = inlineformset_factory(Article, ArticleCategory,
fields=('slug',),
extra=1,
max_num=1)
views.py
class CreateArticle(CreateView):
model = Article
form_class = ArticleCreationForm
template_name_suffix = '_add_form'
def get_success_url(self):
return reverse('accounts:detail', kwargs={'pk': self.object.pk})
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
articleimage_form = ArticleImageFormSet()
articletag_form = ArticleTagFormSet()
articlecategory_form = ArticleCategoryFormSet()
return self.render_to_response(
self.get_context_data(form=form,
articleimage_form=articleimage_form,
articletag_form=articletag_form,
articlecategory_form=articlecategory_form))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
articleimage_form = ArticleImageFormSet(self.request.POST)
articletag_form = ArticleTagFormSet(self.request.POST)
articlecategory_form = ArticleCategoryFormSet(self.request.POST)
if (form.is_valid() and articleimage_form.is_valid() and
articletag_form.is_valid() and articlecategory_form.is_valid()):
return self.form_valid(form, articleimage_form, articletag_form,
articlecategory_form)
else:
return self.form_invalid(form, articleimage_form, articletag_form,
articlecategory_form)
def form_valid(self, form, articleimage_form, articletag_form,
articlecategory_form):
"""
Called if all forms are valid. Creates a Recipe instance along with
associated Ingredients and Instructions and then redirects to a
success page.
"""
self.object = form.save()
obj.author = request.user.username
articleimage_form.instance = self.object
articleimage_form.save()
articletag_form.instance = self.object
articletag_form.save()
articlecategory_form.instance = self.object
articlecategory_form.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, articleimage_form, articletag_form,
articlecategory_form):
"""
Called if a form is invalid. Re-renders the context data with the
data-filled forms and errors.
"""
return self.render_to_response(
self.get_context_data(form=form,
articleimage_form=articleimage_form,
articletag_form=articletag_form,
articlecategory_form=articlecategory_form))
template.html
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
<div class="row">
<div class="medium-9 columns">
{{ form.non_field_errors }}
<h2 class="article-identifier">Add a new article</h2>
<div class="fieldWrapper">
{{ form.title.errors }}
{{ form.title }}
<div id="title_feedback" class="text-right"></div>
</div>
<div class="fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>
</div>
<div class="medium-3 columns">
<div class="button-wrapper">
<input class="button" type="submit" value="Publish">
</div>
<fieldset class="image_upload">
<h2>Add an Image</h2>
{{ articleimage_form.management_form }}
{{ articleimage_form.non_form_errors }}
{% for form in articleimage_form %}
{{ form.id }}
<div class="inline {{ articleimage_form.prefix }}">
{{ form.image.errors }}
{{ form.image.label_tag }}
{{ form.image }}
{{ form.image_name.errors }}
{{ form.image_name.label_tag }}
{{ form.image_name }}
</div>
{% endfor %}
</fieldset>
<fieldset>
<h2>Add a Category</h2>
{{ articlecategory_form.management_form }}
{{ articlecategory_form.non_form_errors }}
{% for form in articlecategory_form %}
{{ form.id }}
<div class="inline {{ articlecategory_form.prefix }}">
{{ form.slug.errors }}
{{ form.slug.label_tag }}
{{ form.slug }}
</div>
{% endfor %}
</fieldset>
<hr />
<fieldset>
<h2>Add a Tag</h2>
{{ articletag_form.management_form }}
{{ articletag_form.non_form_errors }}
{% for form in articletag_form %}
{{ form.id }}
<div class="inline {{ articletag_form.prefix }}">
{{ form.slug.errors }}
{{ form.slug.label_tag }}
{{ form.slug }}
</div>
{% endfor %}
</fieldset>
</div>
</div>
</form>
{%csrf_令牌%}
{{form.non_field_errors}}
添加新文章
{{form.title.errors}}
{{form.title}}
{{form.text.errors}
{{form.text}}
添加图像
{{articleimage_form.management_form}
{{articleimage_form.non_form_errors}
{articleimage_form%}中的表单为%
{{form.id}
{{form.image.errors}
{{form.image.label_tag}
{{form.image}
{{form.image_name.errors}
{{form.image\u name.label\u tag}
{{form.image_name}
{%endfor%}
添加一个类别
{{articlecategory_form.management_form}
{{articlecategory_form.non_form_errors}
{articlecategory_form%}
{{form.id}
{{form.slug.errors}
{{form.slug.label_tag}
{{form.slug}}
{%endfor%}
添加标签
{{articletag_form.management_form}
{{articletag_form.non_form_errors}
{articletag_form%}
{{form.id}
{{form.slug.errors}
{{form.slug.label_tag}
{{form.slug}}
{%endfor%}
使用commit=False
保存表单,在对象上设置用户,然后保存对象。在form\u valid
方法中,您可以使用self.request.user
访问用户。您应该分配用户实例,而不是像代码当前那样分配用户名
obj = form.save(commit=False)
obj.author = self.request.user
...
obj.save
您还应将视图限制为登录用户。您可以使用LoginRequiredMixin
进行此操作
from django.contrib.auth.mixins import LoginRequiredMixin
class CreateArticle(LoginRequiredMixin, CreateView):
根据Django的文档,您可以在覆盖的
form\u valid
方法中(您似乎已经在代码中使用其他对象)将form.instance.author
设置为当前用户(self.request.user
)。然后您可以返回super().form\u valid(form)
在您的情况下,您似乎需要在form\u valid
方法中执行其他操作,因此返回super().form\u valid(form)
可能不一定正确