This post is a work in progress is now working I am glad to say. I have been working on a django site which needs two models updated for one post. It is actually using models very close to that on django-forums and I have created a forms.py file:
class ThreadForm(forms.ModelForm):
class Meta:
model = Thread
exclude = ('forum', 'sticky', 'closed', 'posts', 'views', 'latest_post_time')
def clean_title(self):
title = self.cleaned_data['title']
if not alnum_re.search(title):
raise forms.ValidationError(ugettext("Titles can only contain letters, numbers and underscores"))
if len(title) < 1:
raise forms.ValidationError(ugettext("Please enter a title"))
return title
class PostForm(forms.ModelForm):
class Meta:
model = Post
exclude = ('thread', 'author', 'time', 'related_item')
def clean_body(self):
body = self.cleaned_data['body']
if len(body) < 1:
raise forms.ValidationError(ugettext("Please enter some body text"))
return body
class Meta:
model = Thread
exclude = ('forum', 'sticky', 'closed', 'posts', 'views', 'latest_post_time')
def clean_title(self):
title = self.cleaned_data['title']
if not alnum_re.search(title):
raise forms.ValidationError(ugettext("Titles can only contain letters, numbers and underscores"))
if len(title) < 1:
raise forms.ValidationError(ugettext("Please enter a title"))
return title
class PostForm(forms.ModelForm):
class Meta:
model = Post
exclude = ('thread', 'author', 'time', 'related_item')
def clean_body(self):
body = self.cleaned_data['body']
if len(body) < 1:
raise forms.ValidationError(ugettext("Please enter some body text"))
return body
And then in my views (after importing in the correct models):
@login_required
def groupnewthread(request, slug):
thegroup = get_object_or_404(GroupsOfUser, slug=slug)
if request.method == 'POST':
f = request.POST.copy()
tdata = {
'title': f['title'],
}
pdata = {
'body': f['body'],
}
t = ThreadForm(tdata)
p = PostForm(pdata)
if t.is_valid():
newthread = t.save(commit=False)
newthread.forum = thegroup
if p.is_valid():
newthread.save()
newpost = p.save(commit=False)
newpost.thread = newthread
newpost.author = request.user
newpost.save()
strmessage = 'has created a thread <a href="%s">%s</a>' % (newthread.get_absolute_url(), newthread.title)
usm = UserStatus(user = newpost.author, message = strmessage)
usm.save()
return HttpResponseRedirect(reverse('groupdetail', args=[thegroup.slug]))
else:
t = ThreadForm()
p = PostForm()
objContext = RequestContext(request, {'threadform': t, 'postform': p})
return render_to_response('groups/group_thread_add.html', objContext)
def groupnewthread(request, slug):
thegroup = get_object_or_404(GroupsOfUser, slug=slug)
if request.method == 'POST':
f = request.POST.copy()
tdata = {
'title': f['title'],
}
pdata = {
'body': f['body'],
}
t = ThreadForm(tdata)
p = PostForm(pdata)
if t.is_valid():
newthread = t.save(commit=False)
newthread.forum = thegroup
if p.is_valid():
newthread.save()
newpost = p.save(commit=False)
newpost.thread = newthread
newpost.author = request.user
newpost.save()
strmessage = 'has created a thread <a href="%s">%s</a>' % (newthread.get_absolute_url(), newthread.title)
usm = UserStatus(user = newpost.author, message = strmessage)
usm.save()
return HttpResponseRedirect(reverse('groupdetail', args=[thegroup.slug]))
else:
t = ThreadForm()
p = PostForm()
objContext = RequestContext(request, {'threadform': t, 'postform': p})
return render_to_response('groups/group_thread_add.html', objContext)
Now the bit that is in progress is the returning part of dealing with the form data being bound, but I am going to write a custom handler. This is obviously going to be much easier to handle than an update, which I will have to deal with at a point.
The form HTML looks like this btw:
{% extends "base.html" %}
{% load i18n %}
{% block title %}
{% trans 'Add a new group thread' %}
{% endblock %}
{% block body %}
<h1>{% trans 'Create a new group thread' %}</h1>
<div class="column span-14">
{% if t.errors %}
<h3>{% blocktrans count t.errors|length as count %}Please correct the following error:{% plural %}Please correct the following errors:{% endblocktrans %}</h3>
{% endif %}
{% if p.errors %}
<h3>{% blocktrans count p.errors|length as count %}Please correct the following error:{% plural %}Please correct the following errors:{% endblocktrans %}</h3>
{% endif %}
<table>
<form method="post" action=".">
{{ threadform.as_table }}
{{ postform.as_table }}
<tr><td></td><td><input type="submit" value="{% trans "Update" %}"/></td></tr>
</form>
</table>
</div>
{% endblock %}
{% load i18n %}
{% block title %}
{% trans 'Add a new group thread' %}
{% endblock %}
{% block body %}
<h1>{% trans 'Create a new group thread' %}</h1>
<div class="column span-14">
{% if t.errors %}
<h3>{% blocktrans count t.errors|length as count %}Please correct the following error:{% plural %}Please correct the following errors:{% endblocktrans %}</h3>
{% endif %}
{% if p.errors %}
<h3>{% blocktrans count p.errors|length as count %}Please correct the following error:{% plural %}Please correct the following errors:{% endblocktrans %}</h3>
{% endif %}
<table>
<form method="post" action=".">
{{ threadform.as_table }}
{{ postform.as_table }}
<tr><td></td><td><input type="submit" value="{% trans "Update" %}"/></td></tr>
</form>
</table>
</div>
{% endblock %}
4 Comments
The code and explanation are somewhat unreadable (mac os x, ff3). The code is not indented (big unreadability in python), nor colored. The bottom of the post looks like something went wrong…there is a button that says ‘{% trans’…
I’m not sure you have a great solution to the two model, one form problem. Seems like you’ve just hard-coded your view to refer to a single form. Maybe you want to invest in inheritance or a formset.
It’s a tough problem. Good luck.
Sorry for the unreadable code. I am going to update the design ASAP.
I have now updated the page so you should be able to read the code!
Very good one, saved me time ;D