python - 向复杂的 Django View 添加值

标签 python django view django-models

我正在尝试从 Photographer 模型中获取值字典以显示在我的表单中。之后,用户将选择一个 Photographer,提交表单(连同其他信息),然后将使用 Photographer< 创建模型 A 的实例 作为一个属性。虽然我知道 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 通用 View 来操作对象:

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

然后页面通过 render_page 呈现,看起来像:

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))

如果我的模型是这样的:

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)

您将如何从 Photographer 中获取值以正确地集成到 View 代码中以便稍后在模板中使用?这些值将成为用户从中选择的下拉表单的一部分。一个用法示例会很有帮助。

感谢您的任何想法。

编辑(添加表格)


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

最佳答案

我认为您缺少 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', )

那么您的创建 View 将类似于:

@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)

很难弄清楚您要做什么,我认为您变得过于棘手,因为我从来不需要扩展 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)

关于python - 向复杂的 Django View 添加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11548992/

相关文章:

python - Django:如何根据views.py中的功能显示不同的图像

html - Dreamweaver 中的实时 View 和非实时 View 是否应该显示相同?

python - 将多个正则表达式合并为一个可能为 "catch them all"

django - 在 View 中访问 django celery 结果

c++ - 如何在 C++ 服务器应用程序和 Django Web 应用程序之间进行通信

python - A-z 索引 Django

mysql - 创建在 IF ELSE 语句中进行比较的 View

python - 在未标记的文本语料库上训练 Spacy 以提取 "important phrases"

python - 无法在 WSL 中安装或升级 Python 3.10.8

python - 将 32 位二进制数转换为 4 个独立的 8 位部分的函数