I have these models.
class Storypak(models.Model):
headline = models.CharField('Headline', max_length=200)
pub_date = models.DateField(blank=True)
class Story(models.Model):
storypak = models.OneToOneField('Storypak', blank=True, null=True)
copy = models.TextField(blank=True)
And this view.
def pak_detail(request, pak_id, year, month, day):
pak = Storypak.objects.get(pk=pak_id)
t = loader.get_template('storypak_detail.html')
c = Context ({
'pak' : pak,
})
return HttpResponse(t.render(c))
When I try to use an if statement in my template, a DoesNotExist error is thrown. The documentation I can find indicates that these errors should be silenced. Shouldn't if pak.story resolve False and not throw an error? What am I missing? I think it may have something to do with the OneToOne relationship, but I can't find anything in the docs dealing with this specifically.
Here is the relevant template code as I remember it. I don't have the file on this computer. I'll fix it later if it isn't correct and possibly post the debug info if that would help.
{% if pak.story %}
<p>{{ pak.story.copy }}</p>
{% endif %}
here is a related bug: https://code.djangoproject.com/ticket/10227
here is the source for the if tag: https://code.djangoproject.com/browser/django/trunk/django/template/defaulttags.py#L267
as you see, the tag's render method does not catch anything but VariableDoesNotExist.
You haven't given enough detail to troubleshoot much past the error here, but the simple error message can only be triggered by one statement in your view, that is...
pak = Storypak.objects.get(pk=pak_id)
The pak_id is either invalid, or your model is malformed and a Storypak with that id doesn't exist. That is the only call to an object that would raise a DoesNotExist error. You can verify it is a valid id by adding raise Exception(str(pak_id)) before this line to see what it is attempting to "get." Verify that record exists in the storypak table.
Related
Hello StackOverFlow Members, before i get down to the point, let me retrace my thought/process here to help further slim down my issue. When i click a location object in "location_tree.html" it would redirect me to a new page, "location.html", displaying the location name and its type. From the very same page, the name would be a hyperlink to another page with more details about the "location".
Above is the general flow i want, but when i attempt to click the name from location.html, it redirects me to this error:
NoReverseMatch at /accounts/location/2/
Reverse for 'continent' with keyword arguments '{u'pk': 2}' not found. 1 >pattern(s) tried: ['accounts/location/(?>P\d+)/location_continent/(?P\d+)/']
Some key things to note, i am using python2.7. Lastly, when i remove the {% url %} from location.html everything works perfectly fine.
Here is my working code,
App/models.py:
class Location(models.Model):
title = models.CharField(max_length=255)
location_type = models.CharField(max_length=255, choices=LOCATION_TYPES)
parent = models.ForeignKey("Location", null=True, blank=True,
related_name="parent_location")
def __unicode__(self):
return self.title
class Continent(models.Model):
title = models.CharField(max_length=255)
location = models.OneToOneField(Location, on_delete=models.CASCADE, primary_key=True)
is_an_island = models.BooleanField(default=False)
def __unicode__(self):
return self.location.title
App/views.py:
def view_page_location(request, location_id):
location = Location.objects.get(id=location_id)
if location.location_type == 'Continent':
continent = Continent(location=location, is_an_island=False)
return render(request, 'accounts/location.html', {'location':location, 'continent':continent})
def view_continent(request, pk):
get_continent=get_object_or_404(Continent, pk)
return render(request, 'accounts/location_continent.html', {'get_continent':get_continent})
Project/urls.py:
from App.views import *
url(r'^accounts/location/(?P<location_id>\d+)/', view_page_location, name='location'),
url(r'^accounts/location/(?P<location_id>\d+)/location_continent/(?P<pk>\d+)/', view_continent, name='continent'),
Templates,
location_tree.html:
{% for child in locations %}
{% if child.parent == location %}
<ul>
{{ child }}
location.html:
{% if location.location_type == 'Continent' %}
<h2> Location: {{ location.title }}</h2>
<h3> Type: {{ location.location_type }} </h3></br>
location_continent.html:
<p> hello </p>
I left location_continent pretty generic because i wanted to see if i can get it to work. I feel that something is wrong somewhere in my Urls.py or maybe i'm not properly constructing my views.py.
So the BIG question is, what changes/modifications do i need to alter in order to fix that error? I can't see it myself so i turn to 'you'. Any links for me to read up on and find the answer myself is appreciated as well. I hope my question is clear and not vague.
Two issues.
Your continent url in the location.html doesn't provide location_id argument, you provided only pk. Change it to something like:
{{ location.title }}
In the urls.py, you must add $ at the end of the location url, else there is going to be confusion between location and continent urls. $ has a special meaning in regular expression and means that it requires that the pattern matches the end of the string. Change urls to:
url(r'^accounts/location/(?P<location_id>\d+)/$', view_page_location, name='location'),
url(r'^accounts/location/(?P<location_id>\d+)/location_continent/(?P<pk>\d+)/', view_continent, name='continent')
I have searched around and see that most are pointing to a search that was created by Julien Phalip: http://julienphalip.com/post/2825034077/adding-search-to-a-django-site-in-a-snap
Also the answer seems to be here: Very simple user input in django
However I am very new to Django and wanted to create a view where I actually understand what is happening so I have been going through the official Django and the Tango with Rango tutorials but I do not see a straightforward example of what I am trying to understand in regards to a simple form search. The main question I have is why is POST used in the example instead of GET? I thought POST was used to "create" data entries in mysql whereas GET is used to lookup/search for data entries? Am I missing something fundamental about using one vs the other?
I have the following simple example from my app:
models.py
class hardware(models.Model):
text = models.CharField(max_length=200, unique=TRUE)
pub_date = models.DateTimeField(default=timezone.now)
def __unicode__(self):
return self.text
class Barcode(models.Model):
hardware = models.ForeignKey(Hardware)
text = models.CharField(max_length=50)
pub_date = models.DateTimeField(default=timezone.now)
def __unicode__(self):
return self.text
forms.py
class HardwareForm(forms.modelForm):
class Meta:
model = Hardware
fields = ['text'}
views.py
def hardware_search(request):
if request.method == 'POST':
search_id = request.POST.get('textfield', None)
try:
hardwarename = Hardware.objects.get(text = search_id)
html = ("<H1>%s</H1>", hardwarename)
return HttpResponse(html)
except Hardware.DoesNotExist:
return HttpResponse("no such hardware found")
else:
return render(request, 'search.html')
search.html
<form method="POST" action="/hardware_search.html">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>
My questions are is this the most simple way to request user input to search for and generate the search results? Why is POST used? I plugged in this code and it does seem to work but i just can't understand why.
Secondly how can I display asssociated foreignkey class along with the main class 'hardware' search results? Does the ForeignKey association give a shortcut way of displaying that data as well?
thanks!
The W3 has an excellent introduction to POST vs GET here. There is a lot to be said for why someone might use POST or GET, and what their roles should be. You are probably more interested in the differences from the user's (browser's) perspective. The biggest differences between using POST and GET in a browser, is that the GET request will display the parameters in the URL. Change your form to GET to see for yourself. The user will be taken to:
/hardware_search.html?textfield=Upload%20text
As opposed to where they are taken to when the form action is POST:
/hardware_search.html
The value of the textfield field is still sent to the server, but is not visible in the URL.
There are quite a few other differences in the behavior of GET and POST in form submission. I would highly recommend reading over that introduction by the W3.
You're right, POST is not really appropriate for a search form. Using GET here would be better.
The other thing wrong is that there's no need at all for a ModelForm, or really for any kind of Django form. You're not doing any validation, you're not even using the form for output, so it would be better to leave that out altogether. That makes the view look like this:
def hardware_search(request):
query = request.GET.get('textfield', None)
if query:
try:
hardwarename = Hardware.objects.get(text = query)
html = ("<H1>%s</H1>", hardwarename)
return HttpResponse(html)
except Hardware.DoesNotExist:
return HttpResponse("no such hardware found")
else:
return render(request, 'search.html')
and you can change the form action to GET.
I'm having problem using {% url %} tag in django template.
LINK
Throwing this error:
Caught NoReverseMatch while rendering: Reverse for 'baza.views.thread' with arguments '('',)' and keyword arguments '{}' not found.
What's weird, it works used like this:
{{ category.last_post.thread.pk }}
returns correct value which is '8', also doesn't throw error when I'm using it like this:
LINK
Above code works fine, and redirects to thread.
my urls.py :
...
(r"^temat/(\d+)/$", "thread"),
...
post model:
class Post(models.Model):
title = models.CharField(max_length=60)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True)
thread = models.ForeignKey(Thread)
body = models.CharField(max_length=10000)
thread view:
def thread(request, pk):
posts = Post.objects.filter(thread=pk).order_by("created")
posts = mk_paginator(request, posts, 20) # ZMIEN TAKZE W get_thread_page
t = Thread.objects.get(pk=pk)
return render_to_response("baza/thread.html", add_csrf(request, posts=posts, pk=pk, title=t.title,
element_pk=t.element.pk, media_url=MEDIA_URL, path = request.path))
category model has "last_post" metod which returns last msg posted in this category.
Could someone help me with this annoying problem?
Regards.
Ps. I'm using Django Version: 1.3.1
The problem is that the value of the next expression category.last_post.thread.pk is None or ''. And no Reverse for 'baza.views.thread' with arguments '('',)'.
Arguments ('',) implies that category.last_post.thread.pk is None or ''
trying to use the Django {%url %} template tag and keep failing.
the view is defined in sitename/transfers/views.py (where transfers is the django app name):
def description_ListView(requesst,**kwargs):
template_name = 'transfers/description.html'
o = get_list_or_404(Transfer, description =kwargs['description'])
#print ('o:',o)
context_object_name = "transfer_name_list"
return render_to_response(template_name,{context_object_name:o,'description':kwargs['description']})
(yes, I DO know that this code is a little strange. working on making this more generic and caught in the middle with this annoying problem)
and the url is mapped in transfers/urls.py
url(r'^description/(?P<description>[\w ]+)/$',
'transfers.views.description_ListView',
name = 'description_url')
and in the tag:
{% url "description_url" "blabla" %}
also tried:
{% url "transfers.views.Description_ListView" description = "blabla" %}
the error message:
Exception Type: NoReverseMatch
Exception Value:
Reverse for '"description_url"' with arguments '(u'blabla',)' and keyword arguments '{}' not found.
or when i Tried using the as somename syntax and calling it like this: `{{somename}}. just failed silently and didn't produce anything.
where I also tried importing the Description_ListView from the views and using it directly, didn't help.
Also, following the advice of numerous answers on this subject in various SO questions I changed to double quotes around the view, and reverted to using the url name instead of view but neither helped.
I'll be glad for any help with this
I don't think you need quotes. Try:
{% url description_url "blabla" %}
See https://docs.djangoproject.com/en/dev/topics/http/urls/#naming-url-patterns
I'm relatively new to python/django. I'm having an issue with sending to IDs through my urls.py.
I am trying to add an admin to a business profile page in my project.
My views.py:
#login_required
def make_admin(request, bus_id, user_id):
user = request.user
u = get_object_or_404(User, pk = user_id)
b = get_object_or_404(Business, pk = bus_id)
b.admin.add(u)
followcount = b.followers.count()
photo = BusinessLogo.objects.all().filter(business_link = bus_id)[:1]
return render_to_response('business/followers.html',
{'user':user, 'b':b, 'followcount':followcount, 'photo':photo, 'u':u}, context_instance=RequestContext(request))
In my template I am trying to pass the bus_id as well as the user_id but I keep getting a syntax error, which I am assuming is related to my urls.
My template:
...
{% if follow in b.admin.all %}
[Remove Admin]
{% else %}
[Make Admin]
{% endif %}
...
My urls.py at the moment:
url(r"^make/(?P<bus_id>\d+)/(?P<user_id>\d+)/$", make_admin, name="make_admin"),
url(r"^remove/(?P<bus_id>\d+)/(?P<user_id>\d+)/$", remove_admin, name="remove_admin"),
I am just having a hard time figuring out how to add the user_id to my urls. The above example does not work.
Thanks everyone,
Steve
EDIT: The error Im presented with is:
Caught NoReverseMatch while rendering: Reverse for 'remove_admin' with arguments '(1L, '')' and keyword arguments '{}' not found.
The only thing i can see that seems wrong is {% if follow in b.admin.all %} there's no follow variable in your context in the code you posted.
If you posted more details of your error, or the stack trace, it would be most helpful.
EDIT: Ok, your error is helpful :)
Caught NoReverseMatch while rendering: Reverse for 'remove_admin' with arguments '(1L, '')' and keyword arguments '{}' not found.
This means that the url reversal function got two arguments 1L and ''.
1L i just the integer 1 as a python long integer, the '' means that you passed in None or a blank string.
Since you called the url reversal in your template with {% url remove_admin b.id u.id %} the second argument is the value of u.id. Check the value of the u variable, it seems to not have a valid id attribute, so it's probably not what you expect (I'd guess it's not a User object at all)
You're not referencing the user object in the way you pass it to the context - you pass it as user, but in the template you use u.id.