Django'QuerySet'对象使用modelform没有属性'split'

时间:2012-08-26 04:43:30

标签: django django-forms django-queryset

我在查看更新多字段时遇到问题。它在提交表单后返回。

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'

以下是文件。 Models.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 %}

2 个答案:

答案 0 :(得分:2)

正如错误所描述的那样:QuerySet没有split方法。您无法拨打my_qs.split()

form.cleaned_data['groups']返回已清理的数据;它已经为你处理了表单string-to-python-object转换,在ManyToManyField的情况下最终由python中的QuerySet表示。

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

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

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

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