django blog - post- reply system display replies - django

I have a mini blog app, and a reply system. I want to list all mini blog entries, and their replies, if there are any.
i have in views.py
def profile_view(request, id):
u = UserProfile.objects.get(pk=id)
paginator = New.objects.filter(created_by = request.user)
replies = Reply.objects.filter(reply_to = paginator)
return render_to_response('profile/publicProfile.html', {
'object_list': u,
'list':paginator,
'replies':replies
},
context_instance=RequestContext(request))
and in the template:
<h3>Recent Entries:</h3>
{% for object in list %}
<li>{{ object.post }} <br />
{% for object in replies %}
{{ object.reply }} <br />
{% endfor %}
mention : reply_to is a ForeignKey to New, and New is the name of the 'mini blog' table
But it only shows all the replies for each blog entry, not the reply for every entry, if there is one
thanks

Firstly, please consider giving your variables sensible names. New, list and paginator do not at all describe what those objects actually are - and in some cases they are actively misleading, as with object_list which is not a list at all but a single item.
Secondly, the code is doing exactly what you asked it to (ignoring the fact that the template code you have posted is actually invalid, because you are not nesting the loops properly and redefine the object variable). You get all entries, and all replies, then show the list of all replies underneath every entry.
Instead, you obviously want to get the replies attached to each entry. So delete the lines referring to Reply in the view, and in the template make use of the reverse relationship:
{% for object in list %}
{{ object.post }}
{% for reply in object.reply_set.all %}
{{ reply }}
{% endfor %}
{% endfor %}
Finally, as others have recommended in answer to your other questions, you would be well served by reading the Django tutorial and the Django book, both available freely online.

Related

Django how to mark user-specific objects in queryset to be sent to template?

A newbie in the world of Django. I have what seems to be a general problem but I couldn't find a good answer on the Internet.I need to pass a django queryset to template to display a list. Of those Article objects, some may have been written by the user, I want to highlight/star those particular articles. What is the best practice/solution to achieve this?
for example:
class Article(models.Model) :
article_text = models.CharField(max=32)
written_by = models.CharField()
So I can access the list of all articles in the views.py:
article_list = Articles.objects.all()
And I can filter all the articles by my current logged in user as
my_article = article_list.filter(written_by=current_user)
Within Template I want to display a list of all articles, but 'star' only the ones which have been written by the current logged in user
so in my template I want to do something like this:
{% for article in article_list %}
{% if article.some_flag %}
Starred Article
{% endif %}
{% endfor %}
Question: Is there a good way to annotate 'article_list' objects with a flag some_flag that marks 'my_articles' in views.py?
Or is there a way to do this within template by passing both article_list and mylist and doing the lookup inside the template code?
Something like (code for illustration only):
{% for article in article_list %}
{% if article.pk in mylist.keys %}
Starred Article {{ mylist.pk }}
{% endif %}
{% endfor %}
Any pointers would be very helpful. Hope the question is clear.
Firstly change your Article model to this:
from django.conf import settings
class Article(models.Model) :
article_text = models.CharField(max=32)
written_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
Next in your template check if user is same as the request's user:
{% for article in article_list %}
{% if article.written_by == request.user %}
Starred Article
{% endif %}
{% endfor %}
Also it looks like you have some current_user (don't know what this variable is, perhaps the users username?) which you are using to match the users, if you really don't want to change your Model you can pass that into the context and write {% if article.written_by == current_user %}. But I would recommend to change the Article model for further ease while developing.

Django - ModelForms rendered indexed by foreignKey and that value POSTed

A simple and logical extension of the tutorial polls app would be showing several questions per page with a single 'submit' button. I've got a hybrid design that uses ModelForms for multi-field questions but individually rendered fields for single-field questions. So the standard question_set page is rendered by:
{% load custom_tags %}
{% block question_set %}
<form action="{% url 'polls:answer' user.username %}" method="POST">
{% csrf_token %}
{% for question in page_question_list %}
<hr/>
{% if question.answer_type == "CH" %}
{% include "polls/Choice_Answer_form.html" %} {%endif%}
{% if question.answer_type == "SA" %}
{% include "polls/Short_Answer_form.html" %} {%endif%}
{% if question.answer_type == "LA" %}
{% include "polls/Long_Answer_form.html" %} {%endif%}
{% if question.answer_type == "E3" %}
{% include "polls/EJ_Answer_form.html" with form=forms|get_item:question%}
{%endif%}
{% if question.answer_type == "E4" %}
{% include "polls/EJ_Answer_form.html" with form=forms|get_item:question%}
{%endif%}
{% if question.answer_type == "BS" %}
{% include "polls/brainstorm_form.html" %}
{% endif %}
{% endfor %}
<br/>
<hr/>
<input type="submit" value="Submit" />
</form>
{% endblock %}
I have a sense that I have missed something fundamental about how forms are supposed to work. When you create a ModelForm object and send it out to be rendered, it knows what instance (in my case, question number and user_id) it corresponds to in the model. When it comes back from the browser, that information is gone if you have disabled, read-only'd or hidden those (id, pk etc) fields. You could put that information in the url, but it will only be feasible if you are dealing with a single row of data on each page. In the docs are [examples][1] cheerfully showing how to ModelForm(request=request, instance=instance) but I don't know how to design it so that the request and the instance stay in sync.
Some strategies I've looked into:
bundle needed forms in formsets and use the 'prefix' to differentiate them. Not sure that the question number association can be retained for rendering (suspect it can) or recovered if it is still dropped from the POST data (suspect it can't).
modifying the rendered field-names to include the Key information (question number, user) to prevent them overlapping in html namespace and only the last values being submitted e.g. generate a new field for the form with the data in it to be rendered and presumably passed back or define a function to set a html_field_name in the constructor.
use the form 'auto_id' (see docs) string to give every field a unique name that encodes question number - suspect this ought to be redundant and better handled by the pros in a formset, but see my first idea.
I probably want to try the easiest and best first; any advice gratefully received.
(I had a bunch more links but am not allowed to post them with so little status)
I found that loading and retrieving the question number from the 'prefix' (but not auto_id) field as a string "qNN#" for each form can work (because the prefix is applied to the element name and auto_id applies to the id, and its the name that the POST data uses). I've put all this logic in 'views.py'
The view that catches the submitted form has to look at the keys in request.POST and when it finds a key beginning with q, it works out what question the fields come from and passes the request off with the question to create the form from the request + prefix.
This means that request.POST is sent to my form_instantiator helper function each time there is form_data to be found, rather than submitting them as a group to be iterated over.
I feel guilty of cruelty to Django, somehow.

Accessing Many to Many relationship in Django

I have set up a few models as follows:
Page
Gallery
Image
Gallery and Image share a many to many relationship.
Page can have 1 or 0 galleries.
I have created a gallery with a few images and attached it to a page object.
However, I'm having trouble displaying it in a template.
Can anyone help?
My page view looks like this:
def detail(request, page_id):
p = get_object_or_404(Page, pk=page_id)
return render_to_response('page/detail.html', {'page': p},
context_instance=RequestContext(request))
And the template:
{% block images %}
{% if page.gallery %}
{% for image in page.gallery.image_set.all %}
<a rel="gallery" href="{{ STATIC_URL }}{{ image.image }}"></a>
{% endfor %}
{% endif %}
{% endblock %}`
If I try to output some text within the IF block it comes out OK but not within the loop.
Any advice on getting it to work / generally tidying this up would be greatly appreciated.
Thanks.
If the Gallery-Image relationship is many to many I'm guessing you have an m2m field on your Gallery model, where the m2m manager is the field itself. The manager can be queried just like any other QuerySet: model_instance.mym2mfield.filter().
If your ManyToManyField is called images on the Gallery model, your template would look like this:
{% for image in page.gallery.images.all %}
<a rel="gallery" href="{{ STATIC_URL }}{{ image.image }}"></a>
{% endfor %}
If your ManyToManyField is on your Image model, the default name would be as you describe, unless you specified a related_name in which case you'd use that name.
{% for image in page.gallery.image_set.all %}
Your problem may lie in the way you're accessing the gallery from the page. In your template, try something like the following and see if you get any output:
{{ page.gallery }}
There are instances where certain errors may get ignored in a template.
Also, I'm a little curious how your Page and Gallery are related? Does the Page model have a OneToOneField called "gallery"? Does Gallery have a ForeignKey to Page? In the latter case, you'd access the galleries associated with a page by:
{{ page.gallery_set.all }}
It would be easier to answer this question if you provided some additional information about the fields on your models.

Django, Pulling a Value from a Model based on an ID

I'm relatively new to Django and as a test of my knowledge I'm trying to set up a project where it displays a list of games between anchor tags, when one of the game tags is clicked on, it pulls information about that game from a model using the ID (primary key) relative to that name. For instance the first games ID would be 1 and so on.
However, I am uncertain as to how to approach building a view for this. The only way I was able to get information from a template before was from user input (input tag) and then using request.GET to take the information from the input.
So far in this project, anchor tags are linking to a different URL which has the view which gets the information based on the id, then it should refresh the page and the information should display. Everything should be easy, but I'm just having trouble thinking of a way to get the id of the game based on which link is clicked. Is there a way I can simply set the value of this ID somewhere and reference it in the view, or rather pull the id of the game based on which link is clicked?
Code:
{% extends "base.html" %} <!-- Extends the base models html design-->
{% block title %}Arcade{% endblock %}
{% block content %}
{% if games %}
<p>Found {{ games|length }} game{{ games|pluralize }}</p>
{% for game in games %}
<li>{{ game.game_name }}</li><!--Game Link->
{% endfor %}
{% else %}
<p>There are currently no games in the database.</p>
{% endif %}
{% if results %}
{% endif %}
{% endblock %}
I hope I did an adequate job explaining this problem.
To simplify it further: How do I pull any kind of value from a template?
Thank You
Keith
This is simple. In each iteration of your for loop, you have an object called game, which is presumably a model instance. So you can just do:
<li>{{ game.game_name }}</li>
Or, even better, use the reverse URL functionality:
<li>{{ game.game_name }}</li>
You should look at using AJAX for this.
When the user clicks a tag, have the page asynchronously GET or POST to your django backend. If you want to GET, write a url to the effect of
^/data/game/(\d+)
then grab the id, get your model instance, and return some json or xml.

In Django, how do you construct a formset manually in a template?

I am constructing the pieces of a formset manually in a template. How do I get the hidden fields TOTAL_FORMS and INITIAL_FORMS. Is there a hidden display widget with them in it already there that I can call?
<label>formset title</label>
#formset.TOTAL_FORMS
#formset.INITIAL_FORMS
{% for form in formset.forms %}
{{form.field}}
{{form.id}}
{% endfor %}
You can also shortcut that by just outputting the management form, which consists of those two hidden fields:
{{ formset.management_form }}
I didn't properly cite this info, which can be found at: http://docs.djangoproject.com/en/dev/topics/forms/formsets/
In poking around in the internals I found the answer to my own question:
{{formset.management_form.TOTAL_FORMS}}
{{formset.management_form.INITIAL_FORMS}}