将值添加到复杂Django视图 [英] Adding Values to Complex Django View
问题描述
我正在尝试从摄影师
模型中获取值的字典,以我的形式出现。然后,用户将选择一个摄影师
,提交表单(以及其他信息)和模型 A $ c $将使用 Photographer
作为属性创建c>。虽然我明白ModelForms可以更加友好,但在这种情况下,我必须使用BaseForm:
@login_required
def create_in(request,slug):
element = get_object_or_404(Element,slug = slug)
a = A.objects.create(element = element,user = request.user)
a.save )
return redirect('CreationEditView',pk = a.pk)
urlconf
将用户发送到 create_in,
,用户选择元素
然后被重定向到 CreationEditView
,它使用 BaseUpdateView 从Django通用视图来操纵对象:
class EditView BaseUpdateView):
model = A
form_class = AForm
context_object_name ='a'
page ='edit.html'
def get_element(self) :
返回自己。 object.element
def render_to_response(self,context,** response_kwargs):
element = self.get_element()
return render_page(self.request,element,
self.page,context)
def get_success_url(self):
return reverse('view_all')
def get_context_data(self,** kwargs)
context = super(EditView,self).get_context_data(** kwargs)
返回上下文
def get_queryset(self):
qs = super(EditView,self ).get_queryset()
return qs.filter(active = True,user = self.request.user)
def get(self,request,* args,** kwargs):
self.object = self.get_object()
return super(EditView,self).get(request,* args,** kwargs)
def post(self,request, * args,** kwargs)
self.object = self.get_object()
return super(EditView,self).post(request,* args,** kwargs)
@method_decorator(login_required)
def dispatch(self,request,* args,** kwargs):
return super(EditView,self).dispatch(request,* args,** kwargs)
class CreationEditView(EditView):
def get_queryset(self):
qs = super(EditView,self).get_queryset()
return qs.filter(active = False, user = self.request.user)
def get_success_url(self):
return reverse('create_finished',
kwargs = dict(pk = self.object.pk))
def get_context_data(self,** kwargs):
context = super(CreationEditView,self).get_context_data(** kwargs)
context ['create'] = True
返回上下文
然后通过 render_page
,它看起来像:
def render_page(请求,元素,页面,上下文):
template_name = element_template_name(元素,页面)
try:
tem board = get_template(template_name)
除了TemplateDoesNotExist:
template = get_template('template_location /%s'%page)
context = RequestContext(请求,上下文)
return HttpResponse如果我的模型如下:
$($)
class Photographer(models.Model):
name = models.CharField(max_length = 20)
models = models.ManyToManyField('Model' )
class Model(models.Model):
model = models.CharField(max_length = 20,blank = False)
series = models.ForeignKey('Series',null = true,blank = True)
class A(models.Model):
user = models.ForeignKey(User)
photographer = models.ForeignKey('Photographer',blank = true,null = True)
model = models.ForeignKey('Model',blank = True,null = True)
您将如何从摄影师
中获取值整合到视图代码中以便在模板中使用?这些值将是用户从中选择的下拉单元的一部分。一个使用示例将是非常有用的。
感谢任何想法。
编辑(添加表单)
class AForm(BaseForm):
def __init __(self,data = None,files = None,instance = None,auto_id ='id_%s',
prefix = None,initial = None,error_class = ErrorList,
label_suffix =':',empty_permitted = False)
如果不是实例:
raise NotImplementedError(必须提供实例)
self.instance = instance
object_data = self.instance.fields_dict ()
self.declared_fields = SortedDict()
self.base_fields = fields_for_a(self.instance)
#如果初始化被提供,它应该覆盖实例
如果initial不是None:
object_data.update(initial)
BaseForm .__ init __(self,data,files,auto_id,prefix,object_data,
error_class,label_suffix,empty_permitted)
clean_data = self.cleaned_data
#保存self.instance
fields = field_list(self.instance)的字段值
字段中的字段:
如果field.enable_wysiwyg:
value = unicode(strip(clean_data [field.name]))
else:
value = unicode clean_data [field.name])
return self.instance
解决方案我想你缺少Django编程的基本方面,Django表单。您应该创建一个表单:
class AForm(forms.Form):
model = forms.ModelChoiceField(queryset = Model.objects.all())
photographer = forms.ModelChoiceField(queryset = Photographer.objects.all())
class Meta:
model = A
fields =('model','photographer')
然后你的创建视图看起来像:
@login_required
def create_in(request,slug):
if request.method ==' POST':
form = AForm(request.POST)
如果form.is_valid():
instance = form.save(commit = False)
instance.user = request。
return HttpResponseRedirect(/ somewhere /)
else:
form = AForm()
返回render_to_response('create_in.html',{'form':form} context_instance = context)
很难弄清楚你是什么试图做,我觉得你是非常棘手的,因为我从来没有需要扩展BaseForm,我已经做了很多形式与特殊的过滤器的选择。通常这些都是这样的:
class AForm(forms.Form):
def __init __(self,profile, * args,** kwargs):
super(AForm,self).__ init __(* args,** kwargs)
self.fields ['photographer']。queryset = models.Photographer.objects.filter (profilephotographer__profile = profile)
I am trying to get a dictionary of values from the Photographer
model to appear in my form. Afterwards, the user will select a Photographer
, submit the form (along with other information), and an instance of the model A
will be created with the Photographer
as an attribute. Although I understand ModelForms can be a lot more friendly, I must use BaseForm in this case:
@login_required
def create_in(request, slug):
element = get_object_or_404(Element, slug=slug)
a = A.objects.create(element=element, user=request.user)
a.save()
return redirect('CreationEditView', pk=a.pk)
The urlconf
sends the user to create_in,
where the user selects the element
then is redirected to CreationEditView,
which uses the BaseUpdateView from Django Generic Views to manipulate the object:
class EditView(BaseUpdateView):
model = A
form_class = AForm
context_object_name = 'a'
page = 'edit.html'
def get_element(self):
return self.object.element
def render_to_response(self, context, **response_kwargs):
element = self.get_element()
return render_page(self.request, element,
self.page, context)
def get_success_url(self):
return reverse('view_all')
def get_context_data(self, **kwargs):
context = super(EditView, self).get_context_data(**kwargs)
return context
def get_queryset(self):
qs = super(EditView, self).get_queryset()
return qs.filter(active=True, user=self.request.user)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(EditView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(EditView, self).post(request, *args, **kwargs)
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(EditView, self).dispatch(request, *args, **kwargs)
class CreationEditView(EditView):
def get_queryset(self):
qs = super(EditView, self).get_queryset()
return qs.filter(active=False, user=self.request.user)
def get_success_url(self):
return reverse('create_finished',
kwargs=dict(pk=self.object.pk))
def get_context_data(self, **kwargs):
context = super(CreationEditView, self).get_context_data(**kwargs)
context['create'] = True
return context
The page is then rendered via render_page
, which looks like:
def render_page(request, element, page, context):
template_name = element_template_name(element, page)
try:
template = get_template(template_name)
except TemplateDoesNotExist:
template = get_template('template_location/%s' % page)
context = RequestContext(request, context)
return HttpResponse(template.render(context))
If my models are like:
class Photographer(models.Model):
name = models.CharField(max_length=20)
models = models.ManyToManyField('Model')
class Model(models.Model):
model = models.CharField(max_length=20, blank=False)
series = models.ForeignKey('Series', null=True, blank=True)
class A(models.Model):
user = models.ForeignKey(User)
photographer = models.ForeignKey('Photographer', blank=True, null=True)
model = models.ForeignKey('Model', blank=True, null=True)
How would you go about getting the values from Photographer
to be properly integrated into the view code to use later in the template? These values will be part of a drop down form that a user will select from. A usage example would be very helpful.
Thanks for any ideas.
EDIT (added the form)
class AForm(BaseForm):
def __init__(self, data=None, files=None, instance=None, auto_id='id_%s',
prefix=None, initial=None, error_class=ErrorList,
label_suffix=':', empty_permitted=False):
if not instance:
raise NotImplementedError("Instance must be provided")
self.instance = instance
object_data = self.instance.fields_dict()
self.declared_fields = SortedDict()
self.base_fields = fields_for_a(self.instance)
# if initial was provided, it should override the values from instance
if initial is not None:
object_data.update(initial)
BaseForm.__init__(self, data, files, auto_id, prefix, object_data,
error_class, label_suffix, empty_permitted)
cleaned_data = self.cleaned_data
# save fieldvalues for self.instance
fields = field_list(self.instance)
for field in fields:
if field.enable_wysiwyg:
value = unicode(strip(cleaned_data[field.name]))
else:
value = unicode(cleaned_data[field.name])
return self.instance
解决方案 I think you are missing a fundamental aspect of Django programming, the Django form. You should create a form like:
class AForm(forms.Form):
model = forms.ModelChoiceField(queryset=Model.objects.all())
photographer = forms.ModelChoiceField(queryset=Photographer.objects.all())
class Meta:
model = A
fields = ('model', 'photographer', )
Then your create view would look something like:
@login_required
def create_in(request, slug):
if request.method == 'POST':
form = AForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
return HttpResponseRedirect("/somewhere/")
else:
form = AForm()
return render_to_response('create_in.html', { 'form': form }, context_instance=context)
It's hard to figure out what you are trying to do, I think you are getting overly tricky as I've never needed to extend BaseForm and I've done lots of forms with special filters on the selection. Usually these are done something like:
class AForm(forms.Form):
def __init__(self, profile, *args, **kwargs):
super(AForm, self).__init__(*args, **kwargs)
self.fields['photographer'].queryset = models.Photographer.objects.filter(profilephotographer__profile=profile)
这篇关于将值添加到复杂Django视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!