2

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

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     

表格.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

视图.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)

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

谢谢。

编辑: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 %}
4

2 回答 2

2

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

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

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

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

            group_names = [x.group_nm for x in form.cleaned_data['groups']]
于 2012-08-26T05:50:30.953 回答
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)
于 2012-08-26T05:57:17.300 回答