-
Вот сколько уже бьюсь над проблемой, но никак не могу догнать.
Код отличное работает в Django <= 1.1, но никак не хочет пахать в 1.2 версии
Есть 2 модели:
На основе BookmarkInstance есть форма: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}
и во views.py следующий код: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
следующий код: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))
Все время возвращает мне false. я думал, что проблема, возможно, в crsf, поэтому в шаблоне все сделал так, как говорится в доках, но и это не помогает..if bookmark_form.is_valid():
Повторюсь, код работает на Джанго 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> -
Верный способ пролить свет на невалидность формы — посмотреть к ней в
form.errors.Скорее всего, проблема в том, что в форме у вас всего три поля, а в модели гораздо больше. И среди них есть неопциональный user. Скорее всего, на его отсутствие форма и ругается. Его надо либо вынести из формы через
excludeвMeta, либо просто написав самому полю в моделиeditable=False. -
Иван, спасибо Вам. В правильное направление пнули :) Errors я смотрел, но странным образом не мог понять, что он выдает. Оказывается он сообщает о тех полях, которые не были заполнены, а должны быть. Там содержались bookmark и user.
Видимо в 1.2 версии теперь все построже будет. Оно и к лучшему.
Спасибо еще раз! -
Это работа модельной валидации, которая в 1.2 появилась. Форма в процессе валидации дёргает модель, чтобы узнать, считает ли она данные валидными. И поскольку вы явно не указали
exclude, модель воспринимает отсутствие этих полей как юзерскую ошибку.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
