views:

134

answers:

3

hello, i'm trying to build a mini reply system, based on the user's posts on a mini blog. Every post has a link named reply. if one presses reply, the reply form appears, and one edits the reply, and submits the form.The problem is that i don't know how to take the id of the post i want to reply to. In the view, if i use as a parameter one number (as an id of the blog post),it inserts the reply to the database. But how can i do it by not hardcoding?

The view is:

def save_reply(request):

  if request.method == 'POST':
    form = ReplyForm(request.POST)
    if form.is_valid():
       new_obj = form.save(commit=False)
       new_obj.creator = request.user
       new_post = New(1) #it works only hardcoded
       new_obj.reply_to = new_post
       new_obj.save()
       return HttpResponseRedirect('.')    
  else:
       form = ReplyForm()     
  return render_to_response('replies/replies.html', {
       'form': form,
       }, 
      context_instance=RequestContext(request))  

i have in forms.py:

  class ReplyForm(ModelForm):
    class Meta:
      model = Reply
      fields = ['reply']

and in models:

class Reply(models.Model):
reply_to = models.ForeignKey(New)
creator = models.ForeignKey(User)
reply = models.CharField(max_length=140,blank=False)
    objects = NewManager()   

mentioning that New is the micro blog class

    thanks
+1  A: 

You need to have a hidden field in your form to capture the PK of whichever instance of New the comment is related to.

Since you're using a ModelForm, your Reply model already has the ForiegnKey relationship established. You can set the widget type to be hidden, so your users don't see it..

# forms.py
class ReplyForm(ModelForm):
    class Meta:
        model = Reply
        fields = ['reply', 'reply_to']
        widgets = {
            'reply_to': forms.HiddenInput),
        }

When you initialize the ReplyForm, you can populate the reply_to field like form = ReplyForm({'reply_to': new.pk}) - where new is an instance of New

BTW you might consider changing the name of your New model to something like Post. 'New' is a bit hard to talk about, and a little confusing since 'new' usually means something completely different in a programming context.

Chris Lawlor
hmm.. nope it doesn't solve my problem, yet.
dana
could you update the post with your new code?
Chris Lawlor
+1  A: 

if one presses reply, the reply form appears,

I think this is the part you need to work on. When the reply form is rendered it needs to have the id of the post being replied to with it (the instance of New). This presumably has to come via the request unless you have some other way of keeping track of it?

Something along the lines of:

def save_reply(request):
    ...
    else:
        form = ReplyForm()
        form.reply_to = New.objects.get(id=request.REQUEST["post_id"])

Thus you'll need to ensure that the link which causes the form to be rendered includes a 'post_id' param (or similar - presumably you already have an equivalent, used for displaying the post in question?).

Alongside the

widgets = {
        'reply_to': forms.HiddenInput),
}

code this should render the form as you need it.

The post id has to be passed all the way along the chain

--post_id-> Render Post --post_id-> Render Reply Form --post_id-> Store Reply

pycruft
Ah good point. I was thinking that by 'reply form appears' the form was already rendered in the current template, just hidden by some JS. If the reply form is on a different page however you'd need to pull the post_id out of the request as you've shown.
Chris Lawlor
@pycruft i've done just as you said, and this time my error is: KeyError at /replies/save_reply/ shouldn't i pass as a parameter to the function the reply_to ?But then, as a link for reply, how can i put an url like : r'^profile_view/(?P<id>\d+)/$' ? i mean a href = 'what here'? thank you
dana
+3  A: 

heyy there. i solved the problem,using your advices, but I've created another. I was thinking that as the reply form is in another page, simply clicking on that reply link ain't gonna help me retain the post id anyhow, because the blog page is gone, after i push thet reply button. So, in my view, i 've created a function that holds the id of the blog post as a parameter. It saves just as it should, no problem, but now my problem is: HOW CAN I PASS A LINK LIKE

    url(r'^save_reply/(?P<id>\d+)/$', 
                       save_reply,
                       name='save_reply'), 

(this is what i hold in my urls.py) to the reply under each post? I mean, until now, my reply link was simply calling the function replies/save_reply(i had Reply) but now, when i have the id as a parameter, how can i put it in my a href = 'what here'?

here is my views.py that works right:

 def save_reply(request, id):

 if request.method == 'POST':
    form = ReplyForm(request.POST)
    if form.is_valid():
       new_obj = form.save(commit=False)
       new_obj.creator = request.user

       u = New.objects.get(pk=id)
       new_obj.reply_to = u   

       new_obj.save()
       return HttpResponseRedirect('.')    
 else:
       form = ReplyForm()     
 return render_to_response('replies/replies.html', {
       'form': form,
       }, 
      context_instance=RequestContext(request))  

and i'm callin it by typing in my browser: http://127.0.0.1:8000/replies/save_reply/1/ (for instance) of course, i've removed my foreign key field, as now it is unnecessarry

Thank you!

dana