如何在动态Django ModelChoiceField中设置初始值? [英] How to set initial value in a dynamic Django ModelChoiceField?

查看:169
本文介绍了如何在动态Django ModelChoiceField中设置初始值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为网站创建一个简单的页面版本控制系统。我想要能够将一个页面传递给一个表单,它指向与该页面相关的所有版本,并且该表单下拉列表包含该页面的所有版本,并使初始页面版本成为理想版本在视图中初始化。到目前为止,表单将填写页面的所有版本,但不会选择最初版本的初始项目。



如何设置初始项目的初始项目在表单在视图中初始化时,如果字段被填充,则表单中的字段为



研究:



我在以下问题中尝试过答案,但没有一个解决方案:





示例代码



models.py

从django.db导入模型

从autoslug import AutoSlugField

from django_enumfield import enum

from ..users.models import User


def write_page(name,submitter,content =''):
page = Page。 object.get_or_create(name = name)[0]
page_version = PageVersion.create(页面,提交者,内容)

返回page_version


类状态(enum.Enum):
DISABLED = 0
ACTIVE = 1


类页(models.Model):
name = models.CharField (max_length = 100)
slug = AutoSlugField(populate_from ='name',unique = True)
status = enum.EnumField(Status,default = Status.ACTIVE)
current_version = models.IntegerField (default = 0)

def __unicode __(self):
name_str =(name ='{}',slug ='{}')
return name_str.format (S elf.name,self.slug)

@property
def version(self):
status =(status = {}format(Status.ACTIVE)
order_by =(-version)

return self.pageversion_set.extra(where = status,order_by = order_by)

@property
def all_versions(self):
order_by =(-version,)

返回self.pageversion_set.extra(order_by = order_by)

@property
def ideal(self):
try:
return PageVersion.objects.get(id = self.current_version)
except self.DoesNotExist:
return None

@property
def version(self):
if self.ideal:
return self.ideal.version

return 0

@property
def content(self):
if self.ideal:
return self.ideal.content

return''

@property
def submitter(self) :
if self.ideal:
return self.ideal.submitter

return None

@classmethod
def create(cls,name )
page_object = cls.objects.create(name = name)

return page_object


class PageVersion(models.Model):
parent = models.ForeignKey(Page)
version = models.IntegerField(default = 0)
content = models.TextField()
date = models.DateTimeField(auto_now_add = True)
status = enum.EnumField(Status,default = Status.ACTIVE)
submitter = models.ForeignKey(User)

def __unicode __(self):
name_str = (name ='{}',slug ='{}',version = {})
return name_str.format(self.name,self.slug,self.version)

@property
def name(self):
return self.parent.name

@property
def slug(self):
return self.parent .slug

@classmethod
def创建(cls,page,submitter,content ='',make_current = True):
如果page.all_versions:
current_max_version = max([i.version for i in page.all_versions])
else:
current_max_version = 0

page_version_object = cls(parent = page,submitter = submitter,content = content)
page_version_object.version = current_max_version + 1
page_version_object .save()

如果make_current:
page.current_version = page_version_object.id
page.save()

返回page_version_object

forms.py



<$ p $来自django的表单

从$。$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

$ b class PageVersionForm(forms.Form) = forms.ModelChoiceField(queryset = None)

def __init __(self,* args,** kwargs):
page = kwargs.pop(page)
super PageVersionFor m,self).__ init __(* args,** kwargs)
self.fields [version]。queryset = page.versions

views.py

  from django.shortcuts import get_object_or_404,从django.http导入
导入HttpResponseRedirect,HttpResponseForbidden
from django.core.urlresolvers import reverse

from .models import Page,write_page
from .forms import pageForm,PageVersionForm
from ..helpers import get_pages


def update_page(request,slug):
如果没有request.user.has_perm(can_edit_page):
return HttpResponseForbidden()

page = get_object_or_404(Page,slug = slug)

如果request.method ==POST:
form = PageForm(request.POST)

如果form.is_valid():
content = form.cleaned_data [content]
user = request.user

write_page(name = page.name,submitter = user,content = content)

kwargs = {}
kwargs [slug] = slug

返回HttpResponseRedirect(reverse(pages:detail,kwargs = kwargs))

else =
data = {}
data [content] = page.content

form = PageForm(data)
context = {}

page_version_form = PageVersionForm(page = page)

上下文[form] = form
上下文[page_version_form] = page_version_form
上下文[page ] = page
上下文[user] = request.user
context.update(get_pages())

返回渲染(请求,pages / page_update.html ,上下文)


解决方案

您需要重置选项属性,因为它被缓存在字段上,一旦设置了queryset,即使更新 queryset 属性也不会重新生效。

  def __init __(self,* args,** kwargs):
...
self.fields ['version']。queryset = page.versions
self.fields ['version']。widget.choices = self.fields ['version']。choices

您可以检查Django版本中的 ModelChoiceField 是否具有setter方法命名为 _set_queryset 的?它似乎在github中被修复。


I'm trying to create a simple page versioning system for a website. I want to be able to pass a page into a form, which points to all of the versions related to the page, and have the form dropdown contain all of the versions for that page, and make the initial page version the ideal version when it is initialized in the view. So far, the form will fill with all of the versions for the page, but not select the ideal version as the initial item.

How do I set the initial item of a field in a form if the field gets populated while the form is initialized in the view?

Research:

I have tried the answers in the following questions, but none of them had the solution:

Example code:

models.py

from django.db import models

from autoslug import AutoSlugField

from django_enumfield import enum

from ..users.models import User


def write_page(name, submitter, content=''):
    page = Page.objects.get_or_create(name=name)[0]
    page_version = PageVersion.create(page, submitter, content)

    return page_version


class Status(enum.Enum):
    DISABLED = 0
    ACTIVE = 1


class Page(models.Model):
    name = models.CharField(max_length=100)
    slug = AutoSlugField(populate_from='name', unique=True)
    status = enum.EnumField(Status, default=Status.ACTIVE)
    current_version = models.IntegerField(default=0)

    def __unicode__(self):
        name_str = "(name='{}', slug='{}')"
        return name_str.format(self.name, self.slug)

    @property
    def versions(self):
        status = ("status = {}".format(Status.ACTIVE),)
        order_by = ("-version",)

        return self.pageversion_set.extra(where=status, order_by=order_by)

    @property
    def all_versions(self):
        order_by = ("-version",)

        return self.pageversion_set.extra(order_by=order_by)

    @property
    def ideal(self):
        try:
            return PageVersion.objects.get(id=self.current_version)
        except self.DoesNotExist:
            return None

    @property
    def version(self):
        if self.ideal:
            return self.ideal.version

        return 0

    @property
    def content(self):
        if self.ideal:
            return self.ideal.content

        return ''

    @property
    def submitter(self):
        if self.ideal:
            return self.ideal.submitter

        return None

    @classmethod
    def create(cls, name):
        page_object = cls.objects.create(name=name)

        return page_object


class PageVersion(models.Model):
    parent = models.ForeignKey(Page)
    version = models.IntegerField(default=0)
    content = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    status = enum.EnumField(Status, default=Status.ACTIVE)
    submitter = models.ForeignKey(User)

    def __unicode__(self):
        name_str = "(name='{}', slug='{}', version={})"
        return name_str.format(self.name, self.slug, self.version)

    @property
    def name(self):
        return self.parent.name

    @property
    def slug(self):
        return self.parent.slug

    @classmethod
    def create(cls, page, submitter, content='', make_current=True):
        if page.all_versions:
            current_max_version = max([i.version for i in page.all_versions])
        else:
            current_max_version = 0

        page_version_object = cls(parent=page, submitter=submitter, content=content)
        page_version_object.version = current_max_version + 1
        page_version_object.save()

        if make_current:
            page.current_version = page_version_object.id
            page.save()

        return page_version_object

forms.py

from django import forms

from .models import PageVersion


class PageVersionForm(forms.Form):
    version = forms.ModelChoiceField(queryset=None)

    def __init__(self, *args, **kwargs):
        page = kwargs.pop("page")
        super(PageVersionForm, self).__init__(*args, **kwargs)
        self.fields["version"].queryset = page.versions

views.py

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponseForbidden
from django.core.urlresolvers import reverse

from .models import Page, write_page
from .forms import PageForm, PageVersionForm
from ..helpers import get_pages


def update_page(request, slug):
    if not request.user.has_perm("can_edit_page"):
        return HttpResponseForbidden()

    page = get_object_or_404(Page, slug=slug)

    if request.method == "POST":
        form = PageForm(request.POST)

        if form.is_valid():
            content = form.cleaned_data["content"]
            user = request.user

            write_page(name=page.name, submitter=user, content=content)

            kwargs = {}
            kwargs["slug"] = slug

            return HttpResponseRedirect(reverse("pages:detail", kwargs=kwargs))

    else:
        data = {}
        data["content"] = page.content

        form = PageForm(data)
        context = {}

        page_version_form = PageVersionForm(page=page)

        context["form"] = form
        context["page_version_form"] = page_version_form
        context["page"] = page
        context["user"] = request.user
        context.update(get_pages())

        return render(request, "pages/page_update.html", context)

解决方案

You need to reset choices property as it is cached on the field once queryset is set and is not revalidated even if you update queryset property.

def __init__(self, *args, **kwargs):
    ...
    self.fields['version'].queryset = page.versions
    self.fields['version'].widget.choices = self.fields['version'].choices

Can you check if ModelChoiceField in your Django version has a setter method named _set_queryset? It seems to be fixed in github.

这篇关于如何在动态Django ModelChoiceField中设置初始值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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