Объект Django 'QuerySet' не имеет атрибута 'split' с использованием модели

У меня проблема с получением моего представления для обновления поля manytomany. Он возвращает это после отправки формы.

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 %}

person jabs    schedule 26.08.2012    source источник


Ответы (2)


Точно так, как описывает ошибка: QuerySet не имеет split метода. Вы не можете позвонить my_qs.split().

form.cleaned_data['groups'] возвращает очищенные данные; он уже позаботился о преобразовании строки формы в объект Python, которая в случае ManyToManyField в конечном итоге представлена ​​QuerySet в Python.

Поле даты возвращает объекты даты, IntegerField - целое число, CharFields - строку и т. Д. Таким же образом через очистку формы.

Если вам нужен список group_names, вам нужно будет явно перебирать объекты в QuerySet и извлекать их атрибут group_nm.

            group_names = [x.group_nm for x in form.cleaned_data['groups']]
person Yuji 'Tomita' Tomita    schedule 26.08.2012
comment
Спасибо, что помогли прояснить наборы запросов. Но я все еще не понимаю, как очистить и сохранить набор запросов группы m2m с действием, как только я получу с помощью цикла for. Спасибо за вашу помощь. - person jabs; 27.08.2012
comment
Очистить и сохранить m2m? Звучит как новый вопрос - возможно, вы захотите задать его еще раз и четко указать, что вы ищете. Чтобы очистить m2m, то есть удалить все ассоциации, вы должны вызвать my_m2m_field.clear(). Чтобы добавить их, my_m2m_field.add(*[1, 2, 3, 4]) - person Yuji 'Tomita' Tomita; 27.08.2012
comment
Спасибо, Юджи. Если у меня не получится, я сделаю репост с более четким вопросом. +1 за информацию. - person jabs; 28.08.2012
comment
Не проблема, дайте мне знать, если есть еще что-нибудь! - person Yuji 'Tomita' Tomita; 28.08.2012
comment
Решил, используя ваш подход. Еще раз спасибо! - person jabs; 28.08.2012

Я не уверен, что вам нужно делать все это, на ваш взгляд. Вы можете напрямую сохранить форму в представлении, не создавая вручную объекты и не манипулируя ими.

Кроме того, вам необходимо получить идентификатор активности, чтобы вы могли обновить существующий экземпляр активности.

Обновите urls.py, чтобы эти URL-адреса имели 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)
person Rohan    schedule 26.08.2012
comment
Спасибо за подробный ответ. Однако при таком подходе я получаю другую ошибку: local variable 'act_inst' referenced before assignment. Ошибка ссылается на создание формы, если это не POST. Почему при первоначальном создании формы я хотел бы, чтобы форма ожидала, что переменная будет установлена, если данные не были опубликованы? Еще раз спасибо! - person jabs; 27.08.2012
comment
@jabs о да, когда act_id None act_inst не будет определен. Пожалуйста, проверьте обновленный ответ. - person Rohan; 27.08.2012
comment
На этот раз я получил Caught NoReverseMatch ошибку. Вот мой призыв в шаблоне: <form action="{% url activity activity_save_page.act_id %}" method="post">{% csrf_token %} Я пытался вызвать это значение act_id несколькими способами, но все закончилось той же ошибкой. - person jabs; 28.08.2012
comment
Кроме того, когда я попробовал выполнить обратный поиск reverse('poc.views.activity_save_page'), я получил ту же ошибку: File "<console>", line 1, in <module> 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. Не уверен, правильно ли я сделал ... - person jabs; 28.08.2012
comment
когда я удаляю любую ссылку на переменную в теге шаблона {% url activity.views.activity_save_page %} и просто вызываю страницу, представление формируется правильно и принимает ввод, но не обновляется или вставляется в базу данных. Как я могу понять, где не работает представление? - person jabs; 28.08.2012
comment
@jabs Попробуйте {% url activity.views.activity_save_page act_id%} в шаблоне. Обратите внимание, что вам необходимо передать параметр act_id в свой шаблон. - person Rohan; 28.08.2012
comment
к сожалению, это также возвращает ошибку Caught NoReverseMatch. Я пробовал много разных вызовов для возврата значения id, но пока не нашел, что работает. - person jabs; 28.08.2012
comment
Тег URL @jabs должен быть {% url 'activity.views.activity_save_page' act_id %} в одинарных кавычках вокруг представления. Если это не сработает, возможно, вам следует задать другой вопрос с подробностями, относящимися к этой ошибке. - person Rohan; 28.08.2012
comment
К сожалению, мне не удалось заставить его работать. Спасибо, что посмотрели на него, и (+1) за то, что показали мне пример того, как напрямую сохранить форму без создания объектов. - person jabs; 28.08.2012