将值添加到复杂Django视图 [英] Adding Values to Complex Django View

查看:109
本文介绍了将值添加到复杂Django视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从摄影师模型中获取值的字典,以我的形式出现。然后,用户将选择一个摄影师,提交表单(以及其他信息)和模型 A 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆