[Answer]-How to obtain the ForeignKey id to create a new form linked with the model?


You have multiple choices to solve this. It really depends on the workflow you want to implement in your app.

Choose a description before creating the reward

You will have a page listing all the user’s descriptions : this is your dashboard view.
From here, the user will have to choose the description he wants to add a reward to : by clicking on it, by click on a specific create reward link, etc. This is up to you (ergo/design choice). The main point is to get the description id and pass it to your new_reward view via URLconf (urls.py) with something like this :

# urls.py
urlpatterns = patterns('',
  # your urlpatterns ...
  url(r'^description/(?P<description_id>\d+)/reward/add/$', 'your.app.views.new_reward', name='add-reward'),
  # your urlpatterns ...

This is just an example. You can set the URL as you want. Anyway, when your user will click on the link or the button (or whatever you choosed) the URL will be something like mondomaine.fr/yourappprefix/description/4/reward/add (where 4 is the id of the chosen description – it will be up to you to generate such a link)

With that, in your view, you can retrieve the description object :

#rewardform, I miss the pieces to obtain de description id that will link both table Rewards and Description (and recursively the User table via Description???)
def new_reward(request, description_id):
    description = Description.objects.get_or_404(id=description_id)

Create a reward with a direct link

If such a workflow is not even an option in your case, then smply add a description field to your RewardsForm. With that, your user will be able to aim the description he wants to add a reward to.

To limit the descriptions list to only the ones created by the current user, you could do this in your views.py :

# your code ...
    form = RewardsForm()
    form.fields['description'].queryset = Description.objects.filter(user=request.user)

Maybe you will have to do the save if form.is_valid returns False.

I hope that helps you at least.


In my models.py
I only added a ForeignKey to link my other table (Rewards to User), to be able to get the current id of the current logged user (to restrict the description that do not belongs to the user)

user = models.ForeignKey(User)   

in my urls.py

url(r'^reward_dashboard/(?P<routine_id>\d+)/$', reward_dashboard),
url(r'^reward_create/(?P<description_id>\d+)/$', new_reward),
url(r'^reward_description/(?P<reward_id>\d+)/$', reward_description),

in my views.py:

def reward_dashboard(request, routine_id):    (get the routine_id to only get the dashboard related to the description)
    d = Description.objects.get(id=routine_id) #give the object with description related)
    reward_info = Rewards.objects.filter(user=request.user).filter(description=d) #filter with the right description (from the routine_id passed in) and the right user logged.
    return render_to_response('rewards_dashboard.html', {
        'reward_info': reward_info,
        'd' : d      #i will in my template render the d.id in a link {{reward_id}}

def reward_description(request, reward_id):
    reward_info = Rewards.objects.filter(user=request.user).get(id=reward_id)
    return render_to_response('reward_description.html', {
        'reward': reward_info

def new_reward(request, description_id):
    #description = Description.objects.get_or_404(id=description_id)

    d = Description.objects.get(id=description_id) #get all object with the description_id
    if request.POST:
        form = RewardsForm(request.POST)

        if form.is_valid():
            obj = form.save(commit= False)
            obj.description = d #fill the form with the id that come from my template link
            obj.user = request.user #fill the user with the logged one

            if obj.description == 200:
                return HttpResponseRedirect('/dashboard/')

            return HttpResponseRedirect("/reward_dashboard/%s" % d.id)

        form = RewardsForm()

    args = {}

    args['form'] = form
    args['d'] = d 

    return render_to_response('create_reward.html', args)

I hope my explanation would help.

ps: I will take a look to the get_or_404() to understand how it work because for now i don’t see now the difference in result but for sure would be interesting to redirect the user who try to have access he do not belong.


Leave a comment