1

I am currently using models to have users enter data, using templates (not admin) that is then stored, at which point the users can then see all the data they entered. I would like to also give users the ability to delete specific entries, this would be done using object ids to identify and delete specific objects.

Here is my views.py:

@login_required(login_url='/login/')
def fav(request):
    context = RequestContext(request)

    #This returns all of the data the user has entered
    favorites_list = StockTickerSymbol.objects.filter(user=request.user).order_by('-added_date')
`
    #This is to try to get the ID of every object in favorites_list and append it to a list
    for obj in favorites_list:
        stock_id = []
        stock_id.append(obj.id)

    #Here is where the form is processed to save the data the user has entered
    if request.method == 'POST':
        form = FavoritesForm(request.POST)
        if form.is_valid(): 
            stock = form.save(commit=False)
            stock.user = request.user
            stock.save()
            return redirect(fav)    
        else:   
            print form.errors
    else: 
        form = FavoritesForm()

    context_dict = {'favorites': favorites_list, 'form':form, 'stock_id':stock_id}
    return render_to_response('favorites/favorites.html', context_dict, context)

def delete(request, id):
    stock_to_delete = get_object_or_404(StockTickerSymbol, pk=id).delete()
    return redirect(fav)

Here is my urls.py:

url(r'^favorites/$', views.fav, name='favorites'),
url(r'^add_favorites/$', views.add_fav, name='add favorites'),
url(r'^delete/(?P<id>\d+)/$', views.delete, name='delete')

And this is the part of my template file responsible for deleting

{% for id in stock_id %}
    <div align="right"><a href="/delete/{{id}}">Delete</a></div>
{% endfor %}

My problem with this code, is that the delete link in my template only gives the first object ID for all the links. For example if there are three submissions for the user, and there id's are 1,2,3. The delete link will read "/delete/1" for all the submissions, thus only allowing users to delete their first submission. Any idea on how I can solve this?

ng150716
  • 2,195
  • 5
  • 40
  • 61

1 Answers1

3

Your problem is here:

for obj in favorites_list:
    stock_id = []
    stock_id.append(obj.id)

You are reinitializing inside the loop.

Try this

stock_id = []
for obj in favorites_list:
    stock_id.append(obj.id)

Note that you can also do:

favorites_list = StockTickerSymbol.objects.filter(user=request.user).order_by('-added_date')
stock_ids = list(facorites_list.values_list('id', flat=True)) #IMO - It is a good idea to name a list with plural for readability

Also, in your delete method - See if the user does have permission to delete the object. If not, anyone can hit this url with some random id and start deleting the objects in the database.

I would start off by adding the login_required decorator, followed by adding a created_by or attaching a group associated with the model, which need to be verified before allowing the user to delete the object.

EDIT

{% for fav in favorite_list %}
    <div class="fav">
         {{fav.name}}
    </div>
    <a href="/delete/{{fav.id}}">Delete me</a>
{% endfor %}

Now you can do away with the id list.

karthikr
  • 97,368
  • 26
  • 197
  • 188
  • Thank you, placing the list before the 'for obj in favorites_list' worked. However, now I get multiple delete links. One for every ID. – ng150716 Sep 24 '14 at 21:05
  • Correct, that is what your template code is doing.. See the for loop with the `a` tags ? – karthikr Sep 24 '14 at 21:06
  • Ah yes, I see it. But when I take out the 'for' loop in my template and just try to pass {{ stock_id }}, the delete links have all the id's in it and in brackets, for example: "/delete/[11,12]" Any way to combat this? – ng150716 Sep 24 '14 at 21:09
  • How do you want to combat it ? – karthikr Sep 24 '14 at 21:09
  • Is there anyway to just show the ID that corresponds with each model object rahter than all the Ids – ng150716 Sep 24 '14 at 21:11
  • You already have access to the id of the object via `object.id` . What else do you want? I think you are overthinking.. Can you edit the question with the relevant code and the desired behavior ? – karthikr Sep 24 '14 at 21:13
  • Yes, I do think I am over thinking this (bad habit). But ideally what I'd like to do is take the object id, and link it to the object. So for example if the user entered "hello world" and that object has an id of 1, then I'd like there to be a delete link under hello world with the path "/delete/1" – ng150716 Sep 24 '14 at 22:06