I am using Django to create a site. I have Table called notice as below
Models.py
class Notice(models.Model):
Notice_No=models.AutoField(primary_key=True)
Content=models.TextField(max_length=5000, help_text="Enter Owner Name")
I am using a for loop to display the all these fields on my template page as
Notice No, Content, Date of issue, Date of expiry. I have provided a hyperlink to the all the content values which take it to another HTML play with a proper notice formal of a CHS. Now what I wanna do is if I click on let's say notice of notice no-1. I only want to display the content of that notice on the next page. If I click on notice _no 2, it should only display the contents of that notice. I'm new to python so not sure how to do this. How do I go about this?
Notice.html is the page that displays the table. Noticesoc.html display is where the content should be displayed.
views.py
def notices(request):
Notice_all=Notice.objects.all()[:50]
return render(
request,
'notices.html',
context={'Notice_all':Notice_all}
)
def noticesoc(request):
Notice_all=Notice.objects.all()
return render(
request,
'noticesoc.html',
context={'Notice_all':Notice_all}
)
Send the primary key of the data you want to see in detail.
<td style="color:white; font-family:helvetica; font-size:15px;">
<a class="nav-link" href="{% url 'noticesoc' Notice.pk %}">
Click here to view the contents</a>
</td>
url( r'^noticesoc/(?P<pk>\d+)/$', 'noticesoc')
Then in the view. Use .get to get the information Notice and then render it.
Ex:
def noticesoc(request, pk):
Notice=Notice.objects.get(id=pk)
return render(
request,
'noticesoc.html',
context={'Notice_all':Notice}
)
in reference to this ....
Still doesn't work. Error=local variable 'Notice' referenced before assignment. Can you see my url.py(previous comment) and see if it's correct
you will notice that the model name and the function name are similar hence instead of django differentiating the two it assumes them as similar with the first code to run as the model then the view function
try to use another name for your view function and call the name different and unique from the model name for instance
def noticesoc(request, pk):
Notice=Notice.objects.get(id=pk)
return render(
request,
'noticesoc.html',
context={'Notice_all':Notice}
)
use this instead
def noticesoc(request, pk):
note=Notice.objects.get(id=pk)**
return render(request,'noticesoc.html',context={'note':note}
emphasized text
Related
i am tring to access a page using a slug url, but i keep getting this error The QuerySet value for an exact lookup must be limited to one result using slicing. i thought it would be a filter or get error in my view but i don't know where the error is coming from
view.py
def tutorial_topic_category(request, slug):
tutorial_category = TutorialCategory.objects.get(slug=slug)
tutorial_topic_category = TutorialTopicCategory.objects.filter(tutorial_category=tutorial_category)
context = {
'tutorial_topic_category': tutorial_topic_category,
}
return render(request, 'tutorials/tutorial_topic_category.html', context)
def topic(request, slug, slug2):
tutorial_category = TutorialCategory.objects.get(slug=slug)
tutorial_topic_category = TutorialTopicCategory.objects.filter(tutorial_category=tutorial_category)
topic = Topic.objects.get(slug=slug2, tutorial_topic_category=tutorial_topic_category)
context = {
'topic': topic,
}
return render(request, 'tutorials/topic.html', context)
urls.py
path("<slug>", views.tutorial_topic_category, name='tutorial-topic-category'),
path("<slug>/<slug2>", views.topic, name='topic')
and how do i pass in the slug in my template using django template tag
<a href="{% url 'tutorials:topic' category.slug category.slug2 %}">
In your topic view you are using a filter to get tutorial topic category. This returns a queryset rather than a single item. When you then use it to get 'topic' you are querying based on this set rather than a single equivalent, raising the error. So, instead, to only use the first of the filtered set you could say
topic = Topic.objects.get(slug=slug2, tutorial_topic_category=tutorial_topic_category[0])
...or, if you want to use the full set even though you are only looking for one item
topic = Topic.objects.get(slug=slug2, tutorial_topic_category__in = tutorial_topic_category)
You may also need to to tweak your URL so slug2 comes from the topic slug, as that is the model it will be used to locate the instance of eg:
<a href="{% url 'tutorials:topic' category.slug topic.slug2 %}">
So i'm trying to build something, so that users would be able to report something on site. Here's the model,
class Report(models.Model):
reporting_url = models.URLField()
message = models.TextField()
I created Form for this Model including 'message' field only because 'reporting_url' is something it needs to populate by itself depending upon the specific page from where user has clicked "Report" button.
def report(request):
url_report = ???
if request.method == 'POST':
form = ReportForm(request.POST or None)
if form.is_valid():
new_form = form.save(commit=False)
new_form.reporting_url = url_report
new_form.save()
I was wondering How can I pass the specific url to 'reporting_url' field in form depending on the Page from where user has clicked "Report" button? (Much like s we see on social Networks).
Am I doing this correctly, Or is there a better way for doing this?
Please help me with this code. Thanks in Advance!
If there is a report button on that specific page then I believe you could write custom context processor.
More info: Django: get URL of current page, including parameters, in a template
https://docs.djangoproject.com/en/1.11/ref/templates/api/
Or maybe just write it directly in the views.py in your function and set
url_report = request.get_full_path()
I think you can use the form on the same page of the URL and use:
url_report = request.get_full_path()
in the view, to get the current URL.
Else if you want to create a separate view for the reporting form. You can use
url_report = request.META.get('HTTP_REFERER')
to get the previous or refering URL which led the user to that page.
request.META.get('HTTP_REFERER') will return None if it come from a different website.
I have next task and dont know how to make it.
Web page shows to user list of objects. Every object has 2 button with urls like function_detail and function_change_history. First url need open the page about details of the object and the second url need to open the page about change history. I used get_absolute_url to make second url but dont know how to create first url cause I need to use get_absolute_url again.
models.py:
#reversion.register()
class Function(models.Model):
***FIELDS***
def get_absolute_url(self):
return reverse('project:function_change_history', args=[self.project_id, self.code])
urls.py:
url(r'^(?P<project_code>[0-9a-f-]+)/(?P<function_code>[0-9a-f-]+)/change_history/$',
function_change_history,
name='function_change_history'),
url(r'^(?P<project_code>[0-9a-f-]+)/(?P<function_code>[0-9a-f-]+)/detail/$',
function_detail,
name='function_detail'),
Is it possible to set 2 url in get_absolute_url?
Finally I found the decision. For function_detail I use get_absolute_url and for function_change_history I use in template {% url 'function_change_history' project_code=project.code function_code=function.code %}
I have one data object list in the view and passing it to the template to summarize the the list.
Now, from that template I want to take the data object to the next page (template) to display the details of the data object.
In my view.py
schools = PublicSchools.objects.all()
return render_to_response('searchresult.html', {'schools': schools}, context_instance=RequestContext(request))
In my template searchresult.html, I am listing the summary data of schools.
In turn I want to send the single school object to the next template (dateils.html) to display the details of particular school.
Can some one please help?
Thanks,
You can write another view to handle your requirement
Try this sample code
URL
# pass the selected school id form template to your view
url(r'^school/(?P<school_id>\d+)/$', schoolDetails),
views
def schoolDetails(request, school_id):
try:
school = PublicSchools.objects.get(pk=school_id)
except school.DoesNotExist:
raise Http404
return render(request, 'detail.html', {'school': school})
Hope this helps you :)
I'm tooling around with Django and I'm wondering if there is a simple way to create a "back" link to the previous page using the template system.
I figure that in the worst case I can get this information from the request object in the view function, and pass it along to the template rendering method, but I'm hoping I can avoid all this boilerplate code somehow.
I've checked the Django template docs and I haven't seen anything that mentions this explicitly.
Actually it's go(-1).
<input type=button value="Previous Page" onClick="javascript:history.go(-1);">
This solution worked out for me:
Go back
But that's previously adding 'django.core.context_processors.request', to TEMPLATE_CONTEXT_PROCESSORS in your project's settings.
Back
Here |escape is used to get out of the " "string.
Well you can enable:
'django.core.context_processors.request',
in your settings.TEMPLATE_CONTEXT_PROCESSORS block and hook out the referrer but that's a bit nauseating and could break all over the place.
Most places where you'd want this (eg the edit post page on SO) you have a real object to hook on to (in that example, the post) so you can easily work out what the proper previous page should be.
You can always use the client side option which is very simple:
Back
For RESTful links where "Back" usually means going one level higher:
<input type="button" value="Back" class="btn btn-primary" />
All Javascript solutions mentioned here as well as the request.META.HTTP_REFERER solution sometimes work, but both break in the same scenario (and maybe others, too).
I usually have a Cancel button under a form that creates or changes an object. If the user submits the form once and server side validation fails, the user is presented the form again, containing the wrong data. Guess what, request.META.HTTP_REFERER now points to the URL that displays the form. You can press Cancel a thousand times and will never get back to where the initial edit/create link was.
The only solid solution I can think of is a bit involved, but works for me. If someone knows of a simpler solution, I'd be happy to hear from it. :-)
The 'trick' is to pass the initial HTTP_REFERER into the form and use it from there. So when the form gets POSTed to, it passes the correct, initial referer along.
Here is how I do it:
I created a mixin class for forms that does most of the work:
from django import forms
from django.utils.http import url_has_allowed_host_and_scheme
class FormCancelLinkMixin(forms.Form):
""" Mixin class that provides a proper Cancel button link. """
cancel_link = forms.fields.CharField(widget=forms.HiddenInput())
def __init__(self, *args, **kwargs):
"""
Override to pop 'request' from kwargs.
"""
self.request = kwargs.pop("request")
initial = kwargs.pop("initial", {})
# set initial value of 'cancel_link' to the referer
initial["cancel_link"] = self.request.META.get("HTTP_REFERER", "")
kwargs["initial"] = initial
super().__init__(*args, **kwargs)
def get_cancel_link(self):
"""
Return correct URL for cancelling the form.
If the form has been submitted, the HTTP_REFERER in request.meta points to
the view that handles the form, not the view the user initially came from.
In this case, we use the value of the 'cancel_link' field.
Returns:
A safe URL to go back to, should the user cancel the form.
"""
if self.is_bound:
url = self.cleaned_data["cancel_link"]
# prevent open redirects
if url_has_allowed_host_and_scheme(url, self.request.get_host()):
return url
# fallback to current referer, then root URL
return self.request.META.get("HTTP_REFERER", "/")
The form that is used to edit/create the object (usually a ModelForm subclass) might look like this:
class SomeModelForm(FormCancelLinkMixin, forms.ModelForm):
""" Form for creating some model instance. """
class Meta:
model = ModelClass
# ...
The view must pass the current request to the form. For class based views, you can override get_form_kwargs():
class SomeModelCreateView(CreateView):
model = SomeModelClass
form_class = SomeModelForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
return kwargs
In the template that displays the form:
<form method="post">
{% csrf token %}
{{ form }}
<input type="submit" value="Save">
Cancel
</form>
For a 'back' button in change forms for Django admin what I end up doing is a custom template filter to parse and decode the 'preserved_filters' variable in the template. I placed the following on a customized templates/admin/submit_line.html file:
<a href="../{% if original}../{% endif %}?{{ preserved_filters | decode_filter }}">
{% trans "Back" %}
</a>
And then created a custom template filter:
from urllib.parse import unquote
from django import template
def decode_filter(variable):
if variable.startswith('_changelist_filters='):
return unquote(variable[20:])
return variable
register = template.Library()
register.filter('decode_filter', decode_filter)
Using client side solution would be the proper solution.
Cancel