【问题标题】:Django 'QuerySet' object has no attribute 'split' using modelformDjango 'QuerySet' 对象没有使用 modelform 的属性'split'
【发布时间】:2012-08-21 02:18:04
【问题描述】:

我无法让我的视图更新多对多字段。提交表单后返回。

Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/footbook/Ubuntu One/webapps/fb/poc/../poc/activity/views.py" in activity_save_page
  44.             group_names = form.cleaned_data['groups'].split()

Exception Type: AttributeError at /activity_save/
Exception Value: 'QuerySet' object has no attribute 'split'

这里是文件。 模型.py

class Group (models.Model):
    group_nm = models.CharField(max_length=64)
    group_desc = models.CharField(max_length=250)
    created = models.DateTimeField(auto_now_add=True)
    active_yn = models.BooleanField(default=True)
    def __unicode__(self):
        return self.group_nm



class Activity(models.Model):
    activity_nm = models.CharField(max_length=60)  
    activity_desc = models.CharField(max_length=250)
    startdt = models.DateField()
    enddt = models.DateField()
    crdt = models.DateTimeField(auto_now_add=True,editable=False)
    groups =  models.ManyToManyField(Group)
    upddt = models.DateTimeField(editable=False)
    def  save(self, *args, **kwargs):
        if not self.id:
            self.crdt = datetime.date.today()
        self.upddt = datetime.datetime.today()
        super(Activity, self).save(*args, **kwargs)
    def __unicode__(self):
        return self.name     

forms.py

def make_custom_datefield(f):
    formfield = f.formfield()
    if isinstance(f, models.DateField):
        formfield.widget.format = '%m/%d/%Y'
        formfield.widget.attrs.update({'class':'datePicker', 'readonly':'true'})
    return formfield


class ActivitySaveForm(forms.ModelForm):
    formfield_callback = make_custom_datefield
    def __init__(self, *args, **kwargs):
        super(ActivitySaveForm, self).__init__(*args, **kwargs)
        self.fields['activity_nm'].label = "Activity Name"
        self.fields['activity_desc'].label = "Describe It"
        self.fields['startdt'].label = "Start Date"
        self.fields['enddt'].label = "End Date"
        self.fields['groups'].label ="Group"
    class Meta:
        model = Activity

views.py

def activity_save_page(request):
    if request.method == 'POST':
        form = ActivitySaveForm(request.POST)
        if form.is_valid():
            act, created = Activity.objects.get_or_create(
                activity_nm = form.cleaned_data['activity_nm']
            )
            act.activity_desc = form.cleaned_data['activity_desc']
            if not created:
                act.group_set.clear()
            group_names = form.cleaned_data['groups'].split()
            for group_name in group_names:
                group, dummy = Group.objects.get_or_create(group_nm=group_name)
                act.group_set.add(group)
            act.save()
            return HttpResponseRedirect('/activity/')
    else:
        form = ActivitySaveForm()
    variables = RequestContext(request, {
        'form': form
    })
    return render_to_response('activity_save.html', variables)

我认为如果我不使用模型表单它会起作用,但我需要它来实现this datepicker. 因为它是一个多对多字段,我想在它们输入数据库时​​将它们拆分,但我的查询集失败了。我试过用很多不同的方式改变它,但我被卡住了。我见过很多类似的问题,但它们要么有外键,要么没有模型形式。

谢谢。

编辑: activity_save.html

{% extends "base.html" %}
{% block title %}Save Activity{% endblock %}
{% block head %}Save Activty{% endblock %}
<input class="datePicker" readonly="true" type="text" id="id_startdt" />
<input class="datePicker" readonly="true" type="text" id="id_enddt" />
{% block content %}


<form action="{% url activity.views.activity_save_page act_id%}" method="post">{% csrf_token %}

{{ form.as_p }} 

<input type="submit" value="save it" />
</form>
{% endblock %}

【问题讨论】:

    标签: django django-forms django-queryset


    【解决方案1】:

    正如错误描述的那样:QuerySet 没有split 方法。你不能打电话给my_qs.split()

    form.cleaned_data['groups'] 返回清理数据;它已经为您处理了字符串到python对象的形式转换,在ManyToManyField的情况下,最终由python中的QuerySet表示。

    日期字段返回日期对象,IntegerField 一个整数,CharFields 一个字符串,等等。通过表单清理以相同的方式。

    如果您想要group_names 的列表,您需要显式地遍历QuerySet 中的对象并提取它们的group_nm 属性。

                group_names = [x.group_nm for x in form.cleaned_data['groups']]
    

    【讨论】:

    • 感谢您帮助澄清查询集。但是,一旦我使用for 循环检索,我仍然不知道如何使用活动清除和保存 m2m 组查询集。感谢您的帮助。
    • 清除并保存m2m?听起来像是一个新问题 - 您可能想重新提出它并明确您在寻找什么。要“清除”一个 m2m,也就是删除所有关联,您可以调用 my_m2m_field.clear()。要添加它们,my_m2m_field.add(*[1, 2, 3, 4])
    • 谢谢宇治。如果我无法解决它,我将重新发布一个更清晰的问题。为信息 +1。
    • 没问题,有什么问题请告诉我!
    • 用你的方法解决了。再次感谢!
    【解决方案2】:

    我不确定您是否需要按照您的观点执行所有这些操作。您可以直接将表单保存在视图中,而无需手动创建对象并对其进行操作。

    另外,您需要获取活动的 id,以便您可以更新现有活动实例。

    更新urls.py 以使这些网址具有act_id

    url(r'^activity_app/save/(?P<act_id>\d+)/$', 'activity_app.views.activity_save_page'),
    url(r'^activity_app/save/$', 'activity_app.views.activity_save_page'),
    

    我会将视图更改为:

    def activity_save_page(request, act_id=None):
        act_inst = None
        try:
            if act_id:
               act_inst = Activity.objects.get(id=act_id)
        except Exception:
            pass
        if request.method == 'POST':
            form = ActivitySaveForm(request.POST, instance=act_inst)
            if form.is_valid():
                return HttpResponseRedirect('/activity/')
        else:
            form = ActivitySaveForm(instance=act_inst)
        variables = RequestContext(request, {
            'form': form
            })
        return render_to_response('activity_save.html', variables)
    

    【讨论】:

    • 感谢您的详细回复。不过,我用这种方法得到了一个不同的错误:local variable 'act_inst' referenced before assignment。当它不是 POST 时,错误引用了表单创建。为什么,当最初创建表单时,我想让表单期望设置变量,因为没有发布数据?再次感谢!
    • @jabs 哦,是的,当 act_idNone act_inst 时将不会被定义。请检查更新的答案。
    • 这一次,我收到了Caught NoReverseMatch 错误。这是我在模板中的调用:&lt;form action="{% url activity activity_save_page.act_id %}" method="post"&gt;{% csrf_token %} 我尝试以多种不同的方式调用该 act_id 值,但最终都会出现相同的错误。
    • 另外,当我尝试反向查找 reverse('poc.views.activity_save_page') 时,我得到了同样的错误:File "&lt;console&gt;", line 1, in &lt;module&gt; File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 391, in reverse *args, **kwargs))) File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 337, in reverse "arguments '%s' not found." % (lookup_view_s, args, kwargs)) NoReverseMatch: Reverse for 'poc.views.activity_save_page' with arguments '()' and keyword arguments '{}' not found. 不确定我是否做对了......
    • 当我删除模板标签{% url activity.views.activity_save_page %} 中对变量的任何引用并调用页面时,视图正确形成并接受输入,但不会更新或插入数据库。如何找出视图失败的地方?
    猜你喜欢
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2021-08-05
    • 2017-06-22
    • 2013-05-10
    • 1970-01-01
    • 2014-05-15
    相关资源
    最近更新 更多