1. Хан

    21.07.2010

    0 ↑
    0 ↓
    Вот сколько уже бьюсь над проблемой, но никак не могу догнать.
    Код отличное работает в Django <= 1.1, но никак не хочет пахать в 1.2 версии

    Есть 2 модели:
    class Bookmark(models.Model):

    url = models.URLField(unique=True)
    description = models.CharField(_('description'), max_length=100)
    note = models.TextField(_('note'), blank=True)
    adder = models.ForeignKey(User, related_name="added_bookmarks", verbose_name=_('adder'))
    added = models.DateTimeField(_('added'), default=datetime.datetime.now)

    def __unicode__(self):
    return self.url

    class Meta:
    ordering = ('-added', )

    class BookmarkInstance(models.Model):
    bookmark = models.ForeignKey(Bookmark, related_name="saved_instances", verbose_name=_('bookmark'))
    user = models.ForeignKey(User, related_name="saved_bookmarks", verbose_name=_('user'))
    saved = models.DateTimeField(_('saved'), default=datetime.datetime.now)
    description = models.CharField(_('description'), max_length=100)
    note = models.TextField(_('note'), blank=True)
    tags = TagField()

    def save(self, force_insert=False, force_update=False):
    try:
    bookmark = Bookmark.objects.get(url=self.url)
    except Bookmark.DoesNotExist:
    bookmark = Bookmark(url=self.url, description=self.description, note=self.note, adder=self.user)
    bookmark.save()
    self.bookmark = bookmark
    super(BookmarkInstance, self).save(force_insert, force_update)

    def delete(self):
    bookmark = self.bookmark
    super(BookmarkInstance, self).delete()
    if bookmark.saved_instances.all().count() == 0:
    bookmark.delete()

    def __unicode__(self):
    return _("%(bookmark)s for %(user)s") % {'bookmark':self.bookmark, 'user':self.user}
    На основе BookmarkInstance есть форма:
    class BookmarkInstanceForm(forms.ModelForm):

    url = forms.URLField(label = "URL", verify_exists=True, widget=forms.TextInput(attrs={"size": 40}))
    description = forms.CharField(max_length=100, widget=forms.TextInput(attrs={"size": 40}))
    tags = TagField()

    def __init__(self, user=None, *args, **kwargs):
    self.user = user
    super(BookmarkInstanceForm, self).__init__(*args, **kwargs)
    self.fields.keyOrder = ['url', 'description', 'note', 'tags']

    def clean(self):
    if 'url' not in self.cleaned_data:
    return
    if BookmarkInstance.objects.filter(bookmark__url=self.cleaned_data['url'], user=self.user).count() > 0:
    raise forms.ValidationError(_("You have already bookmarked this link."))
    return self.cleaned_data

    def save(self, commit=True):
    self.url = self.cleaned_data['url']
    return super(BookmarkInstanceForm, self).save(commit)

    class Meta:
    model = BookmarkInstance
    и во views.py следующий код:
    if request.user.is_authenticated():
    if request.method == "POST":
    bookmark_form = BookmarkInstanceForm(request.user, request.POST)

    if bookmark_form.is_valid():
    bookmark_instance = bookmark_form.save(commit=False)
    bookmark_instance.user = request.user
    bookmark_instance.save()
    return HttpResponseRedirect('/')
    else:
    return HttpResponse('Failed')
    else:
    initial = {}
    if "url" in request.GET:
    initial["url"] = request.GET["url"]
    if "description" in request.GET:
    initial["description"] = request.GET["description"].strip()
    if "redirect" in request.GET:
    initial["redirect"] = request.GET["redirect"]

    if initial:
    bookmark_form = BookmarkInstanceForm(initial=initial)
    else:
    bookmark_form = BookmarkInstanceForm()

    return render_to_response("home.html", {"bookmark_form": bookmark_form}, context_instance=RequestContext(request))
    следующий код:
      if bookmark_form.is_valid():
    Все время возвращает мне false. я думал, что проблема, возможно, в crsf, поэтому в шаблоне все сделал так, как говорится в доках, но и это не помогает..
    Повторюсь, код работает на Джанго 1.1 и 1.0.4 (на них только тестировал), но на 1.2 ни в какую, выдает всегда Failed.

    Шаблон выглядит вот так:
    			<form action="/share/" method="post">
    {% csrf_token %}
    {{ bookmark_form.as_p }}
    <input type="submit" value="add bookmark">
    </form>
  2. Иван Сагалаев

    21.07.2010

    0 ↑
    0 ↓

    Верный способ пролить свет на невалидность формы — посмотреть к ней в form.errors.

    Скорее всего, проблема в том, что в форме у вас всего три поля, а в модели гораздо больше. И среди них есть неопциональный user. Скорее всего, на его отсутствие форма и ругается. Его надо либо вынести из формы через exclude в Meta, либо просто написав самому полю в модели editable=False.

  3. Хан

    21.07.2010

    0 ↑
    0 ↓
    Иван, спасибо Вам. В правильное направление пнули :) Errors я смотрел, но странным образом не мог понять, что он выдает. Оказывается он сообщает о тех полях, которые не были заполнены, а должны быть. Там содержались bookmark и user.
    Видимо в 1.2 версии теперь все построже будет. Оно и к лучшему.
    Спасибо еще раз!
  4. Иван Сагалаев

    21.07.2010

    2 ↑
    0 ↓

    Это работа модельной валидации, которая в 1.2 появилась. Форма в процессе валидации дёргает модель, чтобы узнать, считает ли она данные валидными. И поскольку вы явно не указали exclude, модель воспринимает отсутствие этих полей как юзерскую ошибку.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.