i want to create django project with two templates main list and details from the main list using genetic views List view and details views.
the main list work but not work details list.
this my code can somebody to help me ?
urls.py
urlpatterns = [
url(r'^$', ListView.as_view(
model = Test,
queryset = Test.objects.all(),
context_object_name = "test_list",
template_name='blog\test_list.html')),
url((r'^(?P<pk>\d+)-(?P<slug>[-\w]+)/$', DetailView.as_view(
context_object_name="test_list1",
model=Test,
template_name='blog\Test_details.html'
), name="test"),
]
html code test_list
{% for test in test_list %}
<h2> {{test.Title}}</h2>
{% endfor %}
html code test_details
<h2>{{ test.Title }}</h2>
Your link doesn't match your URLs: you're just passing the ID in your link, but the URL pattern is expecting the link and the slug.
I think your problem is a couple of typos:
First in urls, you should change this:
url((r'^(?P<pk>\d+)-(?P<slug>[-\w]+)/$', DetailView.as_view(
to this:
url((r'^(?P<pk>\d+)/$', DetailView.as_view(
Second, (again for the DetailView) your context_object_name is set to test_list1 but your template uses test (the two should match; considering there is no list in this detail view, I would change them to test).
Third, your template_name is set as blog\Test_details.html with the capital T while your html file is actually with lower case t
yeah that correct we success(just delete -(?P[-\w]+) ) to connect first and second template but the second template my Test.Title is empty not show me details from my database,if i use {%for%} show me error message
Related
I'm working on an website where user (if logged in) can perform a calculation and see all of his calculations listed. My website has two groups: Clients and Administrators where Clients are not allowed to see any other members' calculations except their own while Administrators are. Authentication is based on Django's built in User class and for each group I created separate views and templates. Templates have similar behavior but different displaying messages. When Clients want to see their calculations, correct information is displayed but the template rendered is for Administrators rather than for Clients.
views.py
#Administrators' view function
class CalculationListView(generic.ListView):
model = Calculation
paginate_by = 10
#Users' view function
class CalculationsByUserListView(LoginRequiredMixin, generic.ListView):
model = Calculation
paginate_by = 10
def get_queryset(self):
return Calculation.objects.filter(userid=self.request.user)
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('calculations/', views.CalculationListView.as_view(), name='calculations'),
path('calculation/<int:pk>', views.CalculationDetailView.as_view(), name='calculation-detail'),
]
urlpatterns += [
path('mycalculation/', views.CalculationsByUserListView.as_view(), name='mycalcs'),
]
Template names
Administrators: calculation_list.html
Clients: calculations_user.html
EDIT: I mistakenly posted wrong test function. So, here's the one that produced the output referenced few lines below.
test.py
def test_logged_in_uses_correct_template(self):
login = self.client.login(username='testuser1', password='1X<ISRUkw+tuK')
response = self.client.get(reverse('mycalcs'))
# Check if user is logged in
self.assertEqual(str(response.context['user']), 'testuser1')
# Check for the response "success"
self.assertEqual(response.status_code, 200)
# Check if correct template used
self.assertTemplateUsed(response,'cycle/calculations_user.html')
Test response
======================================================================
FAIL: test_logged_in_uses_correct_template (cycle.tests.test_views.CalculationsByUserListViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\DEBIEVEL\Desktop\Work\Edited\django_test\orc2\cycle\tests\test_views.py", line 80, in test_logged_in_uses_correct_template
self.assertTemplateUsed(response, 'cycle/calculations_user.html')
File "C:\ProgramData\Anaconda3\lib\site-packages\django\test\testcases.py", line 661, in assertTemplateUsed
% (template_name, ', '.join(template_names))
AssertionError: False is not true : Template 'cycle/calculations_user.html' was not a template used to render the response. Actual template(s) used: cycle/calculation_list.html, base_generic.html
I tried changing mappings and names of the urls but than I get NoReverseMatch error when I run server but the above test passes. I'm not sure where exactly did I mess up so any help is welcome.
You should specify the name of the templates in the ListViews. By default a ListView [Django-doc] will use the name of the model (here calculation), and then add a suffix _list to it, this thus means that a ListView with Calculation as model, will render the calculation_list.html template.
But this makes no sense for the CalculationsByUserListView, you thus should specify the template_name [Django-doc] with:
class CalculationsByUserListView(LoginRequiredMixin, generic.ListView):
model = Calculation
paginate_by = 10
template_name = 'calculations_user.html'
def get_queryset(self):
return Calculation.objects.filter(userid=self.request.user)
So the issue wasn't in the view definition but in the template. Once I applied #Willem Van Onsem's solution, I started getting NoReverseMatch error for part of my template that actually displays the list. Upon further inspection I discovered it is the for loop in the template that actually raised an error. Since I haven't posted template code before, we were not able to spot it earlier.
The old for loop:
<ul>
{% for calc in calculation_list %}
<li> Performed on {{calc.time_calculated}}
</li>
{% endfor %}
</ul>
New for loop:
<ul>
{% for calc in calculation_list %}
<li> Performed on {{calc.time_calculated}}
</li>
{% endfor %}
</ul>
I also needed to move this specific template out of the templates/cycle folder to only templates/
Once, that was done, everything worked fine.
My intention is to change from interface view -> switch view to process some data and send those data and change to -> test view to display the result. However, nothing in switch view seems to be processed and switch view doesn't change to test view after I hit 'submit' on userInterface.html. My guess is that the problem lies on the HttpResponseRedirect() function or anything related to url paths. Everything worked find with my other project that I worked on my computer. I'm not sure what I need to change to use Django on RaspberryPi.
At first, I found out I didn't import libraries needed for those function. After I imported them, the code was still not working.
I commented out other codes in switch view that do nothing with changing views and just focus on changing view in my switch view.
view.py
def user_interface(request):
return render(request,'zuumcoin/userInterface.html',
{})
def switch(request):
return HttpResponseRedirect(reverse('zuumcoin:test'))
def test(request):
return render(request,'zuumcoin/test.html',{})
userInterface.html
....
<form action="{% url 'zuumcoin:swicht' %} method = "POST">
{% csrf_token %}
...
...
</form>
urls.py
app_name='zuumcoin'
urlpatterns = [
url(r'', views.user_interface, name='interface'),
url(r'switch/', views.switch, name='switch'),
url(r'test/', views.test, name='test')
]
I expect HttpResponseRedirect to direct me to test view instead of being stuck in switch view. If it can do that, I think I can find a way for other part of my code in my switch view to run.
You didn't terminate your regexes. So the first pattern matches every path.
You should do:
url(r'^$', views.user_interface...)
It seems you have typo in your userInterface.html template. change this:
{% url 'zuumcoin:swicht' %}
to this one:
{% url 'zuumcoin:switch' %}
I'm suprised that I cannot access my product detail page through the url and I don't understand why since I've already done this basic thing plenty of times...
I have a page where all my products are displayed, when the user click on a product he is redirected to the product detail, that's it.
Somehow when I click a link linked to the product detail or type de correct path to the url it loads the same page where all the product are shown but it doesn't even call the product detail view, why so ?
Here are the views :
def rcdex(request):
list = Liste.objects.all()
return render(request, 'rcdex.html', {'list':list,})
def rc_detail(request, id):
list = Liste.objects.get(id=id)
return render(request, 'rc_detail.html', {'list':list,})
Here are the urls :
url(r'^', views.rcdex, name="rcdex"),
url(r'^rc/(?P<id>\d+)/$', views.rc_detail, name='rc_detail'),
Here is how I call the rc_detail view on the template :
<th>{{ l.entreprise }}</th>
I don't get why it doesn't show me the correct template (rc_detail.html) but instead reload rcdex.html ?
You haven't terminated your rcdex urlpattern, so it matches everything. You should use a $:
url(r'^$', views.rcdex, name="rcdex"),
you can also do like this..
url(r'^rc/(?P<id>\d+)/$', views.rc_detail, name='rc_detail'),
url(r'^', views.rcdex, name="rcdex"),
There is a common case I encounter, where I can't find a way to split apps.
The case is when a info of two models is related and needs to be in the same template
An example speaks 1000 words: (2 models - pages + comments).
# models.py
class Page(models.Model):
title = models.CharField()
content = models.TextField()
class Comment(models.Model):
page = models.ForeignKey('Page')
content = models.TextField()
# url.py
...
url(r'^page/(?P<page_pk>\d+)/$', views.ViewPage, name='page-view-no-comments'),
url(r'^comment/(?P<comment_pk>\d+)/$', views.ViewComment, name='comment-view'),
url(r'^page-with-comments/(?P<page_pk>\d+)/$', views.ViewPageWithComments, name='page-view-with-comments'),
...
# views.py
def ViewPage(request, page_pk):
page = get_object_or_404(Page, pk=page_pk)
return render(request, 'view_page.html', {'page':page,})
def ViewComment(request, comment_pk):
comment = get_object_or_404(Comment, pk=comment_pk)
return render(request, 'view_comment.html', {'comment':comment})
def ViewPageWithComments(request, page_pk):
page = get_object_or_404(Page, pk=page_pk)
page_comments = Comment.objects.filter(page=page)
return render(request, 'view_page.html', {'page':page,'page_comments':page_comments'})
In this situation, splitting to Page app and Comment app is problematic, because they share a view (ViewPageWithComments) and url.
My options are:
1) Create an Ajax call to comments, which has crawling problems although Google might have fixed it lately.
2) Create a method of page that calls a method in the comments app that returns html with the comments content. If the method needs more arguments I also need to write a custom filter tag.
3) Decide not to split...
Am I missing something and there's another option? When would you prefer (1) vs (2) ?
Note - I created a very simple example to keep the problem general.
You don't need to split anything, you have the pages, and comments have a foreign key to that so you can just iterate over the pages comments
{% for page in pages %}
{% for comment in page.comment_set.all %}
{% endfor}
{% endfor %}
If you want to be able to use the same template for a version of this page without comments you can just wrap the comment for loop in an {% if show_comments %} statement
I've created a very simple blog, but have been running into a couple URL issues. For my tag & specific post views I run into the following issues.
Specific Post View ExampleThese two sites render the same, and would like the second one to render a 404. website.com/post/1/hello-world website.com/post/1/hello-world/non-sense (should render 404)
Tag View
website.com/tag/python: this will render all posts tagged python, great. However...
website.com/tag/python/party: this will render all posts tagged "python/party" instead of rendering a 404.
Here is my URL patterns setup so you can take a look.
url(r'^post/(?P<pk>\d+)/(?P<post_title>)', DetailView.as_view(
model = post,
template_name = "post.html")),
url(r'^post/$', ListView.as_view(
queryset = post.objects.all().order_by("-date"),
template_name = "archives.html")),
url(r'^archives/$', ListView.as_view(
queryset = post.objects.all().order_by("-date"),
template_name = "archives.html")),
url(r'^tag/(?P<tag>[\w|\W]+)', 'tags'),
Updated
Solution for tag:
url(r'^tag/(?P<tag>[\w]+)\W*/$', 'tags'),
Solution for post:
url(r'^post/(?P<pk>\d+)/(?P<post_url>[\w-]+)/$', DetailView.as_view(
model = post,
template_name = "post.html")),
Thank you Huckleberry Finn and krakax for all the help!
Your post URLconf regex
url(r'^post/(?P<pk>\d+)/(?P<post_title>)', DetailView.as_view(
model = post,
template_name = "post.html")),
Should changed to
url(r'^post/(?P<pk>\d+)/(?P<post_title>[-\w]+)/$', DetailView.as_view(
model = post,
template_name = "post.html")),
means URLconf is ending with end-slash
Anyway, Try to define you DetailView URLconf after post ListView. In my opinion if you change your list view and detailview to posts/ and post/ you problem will be solved. The solution is same for tags URLconf issue.
Your regex
r'^tag/(?P<tag>[\w|\W]+)'
means that group tag will contain all caracters after 'tag/'. [\w|\W] means 'all alphanumerics' or 'all but alphanumerics'. This is equivalent to 'all caracters'.
It should be changed to
r'^tag/(?P<tag>[\w]+)\W*'
This will stop your group at first non alphanumeric
Sure, right now I see 2 ways.
First, change to:
r'^tag/(?P<tag>\w+)(?P<end>\W.*)'
(BTW, [] is not necessary in your case) This way, you get the group called 'end' as a parameter of your tag controller and you can test it and redirect to your 404 custom page or generate a 404 classic error.
Second possibility is:
Add another url hook and controller:
url(r'^tag/(?P<tag>\w+)\W*', 'tags404'),
url(r'^tag/(?P<tag>\w+)$', 'tags'),
This way, you forbid any url that contains others caracters than alphanumerics after the 'tag/'.
If you want to allow just one optional '/' at the end, you can write in place of your new hook:
url(r'^tag/(?P<tag>\w+)/?$', 'tags'),