将每个 post 映射到在 Django 中通过外键 post 编辑它的用户?
map each post to the user who posted it by foreign key in django?
我想将每个 post 与 post 编辑它的登录用户联系起来。
models.py
from django.conf import settings
from django.db import models
# Create your models here.
class Campagin(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
media = models.FileField()
description = models.TextField(max_length=220)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __str__(self):
return self.title`
如您所见,post 是由两个不同的用户创建的,但关系显示它是由第一个用户创建的
此图为注册用户..
Views.py
class NewCampagin(LoginRequiredMixin, CreateView):
template_name = 'campagin/new_campagin.html'
model = Campagin
fields = ['title','media','description']
def get_absolute_url(self):
return reverse('campagin:active_campagin')
好的,CreateView
允许您指定 model
和 fields
属性,隐含地 为您创建一个表单。快速提交表单非常简洁,但在您的情况下,您需要在将 Campaign
对象保存到数据库之前进行一些自定义(链接当前 登录 用户) .
因此,您需要先创建自己的表单(创建一个名为 forms.py
的文件,可以在您的 views.py
旁边)并输入此代码:
class CampaignForm(ModelForm): # Import ModelForm too.
def __init__(self, *args, **kwargs):
# We need to get access the currently logged in user so set it as an instance variable of CampaignForm.
self.user = kwargs.pop('user', None)
super(CampaignForm, self).__init__(*args, **kwargs)
class Meta:
model = models.Campaign # you need to import this from your models.py class
fields = ['title','media','description']
def save(self, commit=True):
# This is where we need to insert the currently logged in user into the Campaign instance.
instance = super(CampaignForm, self).save(commit=False)
# Once the all the other attributes are inserted, we just need to insert the current logged in user
# into the instance.
instance.user = self.user
if commit:
instance.save()
return instance
现在我们的 forms.py
已经准备就绪,我们只需要修改您的 views.py
:
class NewCampagin(LoginRequiredMixin, CreateView):
template_name = 'campagin/new_campagin.html'
form_class = forms.CampaignForm # Again, you'll need to import this carefully from our newly created forms.py
model = models.Campaign # Import this.
queryset = models.Campaign.objects.all()
def get_absolute_url(self):
return reverse('campagin:active_campagin') # Sending user object to the form, to verify which fields to display/remove (depending on group)
def get_form_kwargs(self):
# In order for us to access the current user in CampaignForm, we need to actually pass it accross.
# As such, we do this as shown below.
kwargs = super(NewCampaign, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
我的 POST 请求实际上发生了什么?
Note: This is just extra information for the sake of learning. You do
not need to read this part if you don't care about how your class
based view is actually handling your post request.
基本上 CreateView
看起来像这样:
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
"""
View for creating a new object instance,
with a response rendered by template.
"""
template_name_suffix = '_form'
看起来没那么有趣,但如果我们分析一下 BaseCreateView
:
class BaseCreateView(ModelFormMixin, ProcessFormView):
"""
Base view for creating an new object instance.
Using this base class requires subclassing to provide a response mixin.
"""
def post(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).post(request, *args, **kwargs)
我们可以看到我们继承了两个非常重要的 类 ModelFormMixin
和 ProcessFormView
。现在,return super(BaseCreateView, self).post(request, *args, **kwargs)
行本质上调用了 ProcessFormView
中的 post
函数,它看起来像这样:
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance with the passed
POST variables and then checked for validity.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
如您所见,您的 CreateView
实际上只是归结为这个 post
小函数,它只是获取指定的表单并验证并保存它。此时有2个问题要问。
1) form = self.get_form()
做了什么,因为我什至没有指定我的表格?
2) self.form_valid(form)
实际上在做什么?
为了回答第一个问题,self.get_form()
本质上调用了另一个函数 form_class = self.get_form_class()
而这个函数实际上是在 ModelFormMixin 中找到的(继承自! ):
def get_form_class(self):
"""
Returns the form class to use in this view.
"""
if self.fields is not None and self.form_class:
raise ImproperlyConfigured(
"Specifying both 'fields' and 'form_class' is not permitted."
)
if self.form_class:
return self.form_class
else:
if self.model is not None:
# If a model has been explicitly provided, use it
model = self.model
elif hasattr(self, 'object') and self.object is not None:
# If this view is operating on a single object, use
# the class of that object
model = self.object.__class__
else:
# Try to get a queryset and extract the model class
# from that
model = self.get_queryset().model
if self.fields is None:
raise ImproperlyConfigured(
"Using ModelFormMixin (base class of %s) without "
"the 'fields' attribute is prohibited." % self.__class__.__name__
)
# THIS IS WHERE YOUR FORM WAS BEING IMPLICITLY CREATED.
return model_forms.modelform_factory(model, fields=self.fields)
如您所见,此函数是您的表单隐式 创建的地方(请参阅最后一行)。我们需要为您的情况添加更多功能,因此我们创建了自己的 forms.py
并在 views.py
中指定了 form_class。
要回答第二个问题,我们需要查看函数(self.form_valid(form)
)调用的源代码:
def form_valid(self, form):
"""
If the form is valid, save the associated model.
"""
# THIS IS A CRUCIAL LINE.
# This is where your actual Campaign object is created. We OVERRIDE the save() function call in our forms.py so that you could link up your logged in user to the campaign object before saving.
self.object = form.save()
return super(ModelFormMixin, self).form_valid(form)
所以这里我们只是简单地保存对象。
希望对您有所帮助!
更多信息请见 https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#createview
我想将每个 post 与 post 编辑它的登录用户联系起来。
models.py
from django.conf import settings
from django.db import models
# Create your models here.
class Campagin(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
media = models.FileField()
description = models.TextField(max_length=220)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
def __str__(self):
return self.title`
如您所见,post 是由两个不同的用户创建的,但关系显示它是由第一个用户创建的
此图为注册用户..
Views.py
class NewCampagin(LoginRequiredMixin, CreateView):
template_name = 'campagin/new_campagin.html'
model = Campagin
fields = ['title','media','description']
def get_absolute_url(self):
return reverse('campagin:active_campagin')
好的,CreateView
允许您指定 model
和 fields
属性,隐含地 为您创建一个表单。快速提交表单非常简洁,但在您的情况下,您需要在将 Campaign
对象保存到数据库之前进行一些自定义(链接当前 登录 用户) .
因此,您需要先创建自己的表单(创建一个名为 forms.py
的文件,可以在您的 views.py
旁边)并输入此代码:
class CampaignForm(ModelForm): # Import ModelForm too.
def __init__(self, *args, **kwargs):
# We need to get access the currently logged in user so set it as an instance variable of CampaignForm.
self.user = kwargs.pop('user', None)
super(CampaignForm, self).__init__(*args, **kwargs)
class Meta:
model = models.Campaign # you need to import this from your models.py class
fields = ['title','media','description']
def save(self, commit=True):
# This is where we need to insert the currently logged in user into the Campaign instance.
instance = super(CampaignForm, self).save(commit=False)
# Once the all the other attributes are inserted, we just need to insert the current logged in user
# into the instance.
instance.user = self.user
if commit:
instance.save()
return instance
现在我们的 forms.py
已经准备就绪,我们只需要修改您的 views.py
:
class NewCampagin(LoginRequiredMixin, CreateView):
template_name = 'campagin/new_campagin.html'
form_class = forms.CampaignForm # Again, you'll need to import this carefully from our newly created forms.py
model = models.Campaign # Import this.
queryset = models.Campaign.objects.all()
def get_absolute_url(self):
return reverse('campagin:active_campagin') # Sending user object to the form, to verify which fields to display/remove (depending on group)
def get_form_kwargs(self):
# In order for us to access the current user in CampaignForm, we need to actually pass it accross.
# As such, we do this as shown below.
kwargs = super(NewCampaign, self).get_form_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
我的 POST 请求实际上发生了什么?
Note: This is just extra information for the sake of learning. You do not need to read this part if you don't care about how your class based view is actually handling your post request.
基本上 CreateView
看起来像这样:
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
"""
View for creating a new object instance,
with a response rendered by template.
"""
template_name_suffix = '_form'
看起来没那么有趣,但如果我们分析一下 BaseCreateView
:
class BaseCreateView(ModelFormMixin, ProcessFormView):
"""
Base view for creating an new object instance.
Using this base class requires subclassing to provide a response mixin.
"""
def post(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).post(request, *args, **kwargs)
我们可以看到我们继承了两个非常重要的 类 ModelFormMixin
和 ProcessFormView
。现在,return super(BaseCreateView, self).post(request, *args, **kwargs)
行本质上调用了 ProcessFormView
中的 post
函数,它看起来像这样:
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance with the passed
POST variables and then checked for validity.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
如您所见,您的 CreateView
实际上只是归结为这个 post
小函数,它只是获取指定的表单并验证并保存它。此时有2个问题要问。
1) form = self.get_form()
做了什么,因为我什至没有指定我的表格?
2) self.form_valid(form)
实际上在做什么?
为了回答第一个问题,self.get_form()
本质上调用了另一个函数 form_class = self.get_form_class()
而这个函数实际上是在 ModelFormMixin 中找到的(继承自! ):
def get_form_class(self):
"""
Returns the form class to use in this view.
"""
if self.fields is not None and self.form_class:
raise ImproperlyConfigured(
"Specifying both 'fields' and 'form_class' is not permitted."
)
if self.form_class:
return self.form_class
else:
if self.model is not None:
# If a model has been explicitly provided, use it
model = self.model
elif hasattr(self, 'object') and self.object is not None:
# If this view is operating on a single object, use
# the class of that object
model = self.object.__class__
else:
# Try to get a queryset and extract the model class
# from that
model = self.get_queryset().model
if self.fields is None:
raise ImproperlyConfigured(
"Using ModelFormMixin (base class of %s) without "
"the 'fields' attribute is prohibited." % self.__class__.__name__
)
# THIS IS WHERE YOUR FORM WAS BEING IMPLICITLY CREATED.
return model_forms.modelform_factory(model, fields=self.fields)
如您所见,此函数是您的表单隐式 创建的地方(请参阅最后一行)。我们需要为您的情况添加更多功能,因此我们创建了自己的 forms.py
并在 views.py
中指定了 form_class。
要回答第二个问题,我们需要查看函数(self.form_valid(form)
)调用的源代码:
def form_valid(self, form):
"""
If the form is valid, save the associated model.
"""
# THIS IS A CRUCIAL LINE.
# This is where your actual Campaign object is created. We OVERRIDE the save() function call in our forms.py so that you could link up your logged in user to the campaign object before saving.
self.object = form.save()
return super(ModelFormMixin, self).form_valid(form)
所以这里我们只是简单地保存对象。
希望对您有所帮助!
更多信息请见 https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#createview