Reputation: 6320
I have 3 database model - Semester, Section and Notecard
The Notecard model has a "Known" field that I use to classify the Notecard objects into "piles" as Known (1) or Unknown (0):
class Notecard(models.Model):
notecard_name = models.CharField(max_length=50)
notecard_body = models.TextField()
section = models.ForeignKey(Section)
known = models.BooleanField()
I have two views - known_list and unkown_list that displays the corresponding piles (known_list below for reference):
def known_list(request, section_name):
try:
section = Section.objects.get(section_name__iexact = section_name)
except Section.DoesNotExist:
raise Http404
known_list = Notecard.objects.filter(known=1, section=section)
paginator = Paginator(known_list, 1)
if known_list:
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
known = paginator.page(page)
except (EmptyPage, InvalidPage):
known = paginator.page(paginator.num_pages)
context = RequestContext(request)
return render_to_response('notecards/known.html', {"known": known}, context_instance=context)
else:
url = reverse('notecard_list', kwargs={'section_name': section_name})
return HttpResponseRedirect(url)
This view brings in the section_name from the previous view to display all the Notecard objects that are in the section that was clicked on, and in the known pile.
In the template below, you can see that I paginate the notecards to one a page:
{% extends "base.html" %}
{% block content %}
<h1 class='title'><a href="/">NoteCards!</a></h1>
{% for notecard in known.object_list %}
<h1 class='notecard'>{{ notecard.notecard_name }}</h1>
<h3 class='notecard'>{{ notecard.notecard_body }}</h3>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if known.has_previous %}
<a class="navlink" href="?page={{ known.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ known.number }} of {{ known.paginator.num_pages }}
</span>
{% if known.has_next %}
<a class="navlink" href="?page={{ known.next_page_number }}">next</a>
{% endif %}
</span>
</div>
{% endblock %}
urls.py
urlpatterns += patterns('',
url(r'^(?P<section_name>[\w|\W]+)/unknown/$', unknown_list, name="unknown_list"),
url(r'^(?P<section_name>[\w|\W]+)/known/', known_list, name="known_list"),
url(r'^semester/(?P<semester_name>[\w|\W]+)/', section_list, name="section_list"),
url(r'^section/(?P<section_name>[\w|\W]+)/', notecard_list, name="notecard_list"),
url(r'^notecard/(?P<notecard_name>[\w|\W]+)/', notecard_detail, name="notecard_detail"),
url(r'^$', semester_list, name="semester_list"),
)
That said, I would like to add a "Send to Unknown" button that will allow users to send the notecard whose page they are currently on to the unknown pile (Simply changing the known field to = 0, removing the notecard from the pagination list, and moving to the next page in the pagination).
I have tried replicating my new_notecard view which contains a full form of the model, but I was unable to figure out how to update a single field.
I have also tried using queryset.update() but was unable to figure out how to capture the pk from the specific notecard.
I've been trying to figure this out on my own for over a month, but I've been unsuccessful. Thank you in advance.
EDIT:
It seems like my hang up is pulling the pk of the notecard on each page of the pagination. For example, if I am on page 3 of the pagination - when the "Send to Unknown" button is pushed, how do I identify that notecard in my view and update it from known (1) to unknown (0)
Upvotes: 1
Views: 2613
Reputation: 2481
you must create a specific view with a specific url to handle this, for example:
# urls.py
url(r'^movetounknown/(?P<notecard_id>[\w|\W]+)/', notecard_move_to_unknown)
# views.py
@require_POST
def notecard_move_to_unknown(request, notecard_id):
notecard = Notecard.objects.get(pk=notecard_id)
notecard.known = False
notecard.save()
return HttpResponseRedirect(request.POST['next'])
# template
{% for notecard in known.object_list %}
<h1 class='notecard'>{{ notecard.notecard_name }}</h1>
<h3 class='notecard'>{{ notecard.notecard_body }}</h3>
<form action="{% url views.move_to_unknown notecard.pk %}" method="post">
<input type="hidden" name="next" value="{% url known_list known.section.section_name %}?page={{known.paginator.number}}"/>
<input type="submit" value="Move to unknown list"/>
</form>
{% endfor %}
You also can pass the notecard id as a post parameter.
The next
parameter tells where to go after the change, here I choose the same page of the known list because once the current card is removed the next one is at this index
Upvotes: 2
Reputation: 36506
Capturing the pk of a specific notecard object can be done by defining a specific url for that notecard. For example:-
# urls.py
url(r'^notecard/(?P<notecard_id>\d+)/$',
'notecard',
name='notecard'),
# corresponding views.py
def notecard(request, note_card_id):
notecard = get_object_or_404(Notecard, pk=note_card_id)
template = 'notecard/notecard.html'
template_vars = {'notecard': notecard}
render(request, template, template_vars)
# notecard/notecard.html
<h2>{{ notecard.notecard_name }}</h2>
<p>{{ notecard.notecard_body }}</p>
You can also define a form with the notecard id/pk being a hidden field for submission and updating into your database (and of course, you will need to update your view function correspondingly).
In essence, to update a specific notecard object, you will simply do in your view function (with form submission or, if you prefer, a pure ajax implementation in your listing page) like this
notecard.known = False
notecard.save()
Upvotes: 0