I'm trying to display values associated with a foreign key while rendering a Django Template. I've emulated other answers on this site to no avail.
I'm using the package django-simple-history to track changes to all the records in my database's primary table. This table has a foreign key named history_user_id which corresponds to the id in the django table auth_user.
According to this example (Display foreign key value in django template) I should be able to display the usernames of users who have amended the database by using the following code:
<ul>{% for item in history %}
<li>{{item.history_user_id.username}}</li>
</ul>{% endfor %}
where history is defined in my views.py as
def view_history(request,pk):
project = Project.objects.get(pk=pk)
history = project.history.all()
return render(
request,
"projects/view_history.html",
{
"project": project,
"history": history,
}
)
The template I create can interpret item.history_user_id, and I can manually look into the table auth_user to the corresponding username, but when I try to use the template to render the username I get a blank instead. Am I missing a step?
If I see it correctly item.history_user_id is the id of the user who did the change. This is an integer, which of course does not have any property called user. If a django template hits a non-existant variable it will just leave it blank (and not raise an error). Therefore you a seeing nothing in your template.
So change your code to get the user rather than the user_id
<ul>{% for item in history %}
<li>{{item.history_user}}</li>
</ul>{% endfor %}
This is described in the docs.
Related
Please, I would like to render a varible in django template, kind of {{ user.name }} inside of a textfield from database, that I filled up on the django admin. like this
how can I manage to achieve it please, thank you all, have a good day.
If you are using custom form then try using
value={{ user.name }}
and if you are letting Django render the form for you as like "form.as_p" then you can try
form_instance = Form(request.POST)
and send the form instance to the template
After a while of looking, I found out that the right solution of accomplishing such a thing is by creating a filter or tag and affecting it to the content rendered from the database based on the Django documentation link to create custom filters and tags, I created a filter that takes the content as a variable and scanned whenever I find the variable I replace it with the content from the database
# This code goes in the filter logic
values = model.objects.all()
content.replace('{{ user.name }}',values.name)
# This is how the content is rendered on the template
{{content | filter_name}}
I am using the Django inbuilt user authentication system, from from django.contrib.auth.models import User. And I have realised that in the admin page it always displays the username of the user. Is it possible to change the def __str__ (self): method of that function to display a customized one, something like this.
def __str__ (self):
return f"{self.first_name}"
For any such changes, you should refer to the template that's rendering it. Here, it is the Django Admin's base.html template.
As you can see in this line in the file, it searches for both short_name and user_name in that order and displays the first one available.
{% block welcome-msg %}
{% translate 'Welcome,' %}
<strong>
{% firstof user.get_short_name user.get_username %}
</strong>.
{% endblock %}
And get_short_name returns the first name of the user. So, your user does not have their first name defined and hence it's showing up their username.
NOTE : Please check your Django version's documentation since this has been implemented after version 1.5 and above, and is valid only for greater versions.
I highly recommend to extend the auth user model and thus you can do a lot of customizations sooner or later.
You can use lambda function to alter the __str__() method of auth user as
from django.contrib.auth.models import User
User.__str__ = lambda user_instance: user_instance.first_name
Note: This snippet should get executed on the Django server initialization
If you are trying to change the username which is shown at the top-right-corner (as mentioned by #amit sigh ), set the lambda function for get_short_name as,
from django.contrib.auth.models import User
User.get_short_name = lambda user_instance: f"Prefix : {user_instance.first_name} : Suffix"
I wanna use the Django session variable on models.py file. How can I do it?
I want to get the user's Pincode/zip and have to run a query using that.
pin_code = #wanna get from session
price = ProductPrice.objects.get(product=self.pk, pincode=pin_code)
I need to get Pincode from the session.
In your model method you don't have access to the request so you do not have access to the session. One way that you could call the method with the session is to add a template tag that passes the value from the session to your method
#register.simple_tag(takes_context=True)
def price(context, product):
return product.get_price(pin_code=context.request.session.get('pin_code'))
In your template you would use the following, if the above code was added to a file with the path app_name/templatetags/product_tags.py
{% load product_tags %}
{% price item %}
Docs on where to put custom template tags
I am trying access price_retail field in product detail page using template tag purchase_info_for_product. but am not getting the value of price_retail.
{% purchase_info_for_product request product as session %}
{{ session.price.price_retail|currency:session.price.currency }}
but i am able to access fields like incl_tax, excl_tax
It looks like you're trying to access a field from the stock record - this is not the same as the Price object that the strategy provides.
The stock record is available on the parent object though, and can be accessed with:
session.stockrecord.price_retail
Note: The price_retail field will be removed in Oscar 2.1
I asked this question earlier, but now I'm having trouble sorting out how to use drop downs (or even better, autofill fields) for one of the forms of a multi-form view.
The models in play are Book, BookDetails, and Genre. BookDetails is a linking table to Genre (and other similar tables) so that I can have a static list of genres etc. with unique IDs and foreign keys to BookDetails.
Right now I have this:
#views.py
def BookFormView(request):
genre = Genre.objects.all()
if request.method == "POST":
book_form = BookForm(request.POST, prefix='book')
bookdetails_form = BookDetailsForm(request.POST, prefix='bookdetails')
selected_genre = get_object_or_404(Genre, pk=request.POST.get('genre_id'))
genre.id = selected_genre
genre.save()
if book_form.is_valid() and bookdetails_form.is_valid():
book_form.save()
bookdetails_form.save()
return HttpResponseRedirect("/books/")
else:
book_form = bookForm(prefix='book')
bookdetails_form = BookDetailsForm(prefix='bookdetails)
return render(request, 'books/createbook.html',
{'book_form' : book_form,
'bookdetails_form': bookdetails_form,
'genre':genre,})
#createbook.html
<select name="genre", id="genre" form="bookform">
{% for entry in genre %}
<option value="{{ entry.id }}">
{{ entry.name }}
</option>
{% endfor %}
</select>
The form displays properly on the page, dropdown menu with options from the database included. However, when I hit submit to store the information to the database I get an error saying No Genre matches the given query The other posts on SO that regard this error don't seem to be from the same context. I think that it might be something to do with selecting a name but storing an id (for the genres), but otherwise I'm at a loss.
Normally, the way you'd do this with a form in django is not by manually pulling something out of the POST dict, but by using a ModelChoiceField:
https://docs.djangoproject.com/en/1.8/ref/forms/fields/#modelchoicefield
Was there a specific reason you didn't do that?
Also, it appears you're using the genre variable incorrectly for two different things. You initialize it with a queryset, but then try to treat it like a Genre instance later in the code. That's going to cause problems not to mention the fact that I don't think your genre.id = ... line is going to do what you expect it to.
Also, it's against style conventions to use title-casing for function names. If you're going to be doing much coding in Python, it's probably worth taking a look at the officially accepted PEP8 style guide here:
https://www.python.org/dev/peps/pep-0008/
There are a few other problems in the code but I'm not sure it's worth calling them out.