Get Current Url Without Parameters in Django - python

I have a url like below:
url(r'^board/(?P<pk>\d+)$', board_crud, name='board_update'),
I want to get current view 'board' without parameters so that i can redirect to it.
I want to redirect to current view(without param) in same view(with param).
Thanks in Advance.

I believe you want to do something like this:
urls.py
url(r'^board/$', board_redirect, name='board_redirect'),
url(r'^board/(?P<pk>\d+)/$', board_crud, name='board_update'),
PS: Note the ending /, it's a good idea to always end the url
patterns with a forward slash, for consistency (except cases where you
are return a url like sitemap.xml for example).
Then, you would need to create a view like this:
views.py
from django.shortcuts import redirect
from .models import Foo
def board_redirect(request):
latest = Foo.objects.values('pk').order_by('-date').first()
return redirect('board_update', pk=latest['pk'])
The queryset would define the logic you want to implement. I don't have more info on your application. In this example you would always show the "latest" object based on a "date" field. Hope it makes sense.

Related

Django using a variable in multiple views/templates

I have a table with results from a search. This means there are no models here. The problem is that i'd like to go to a detail page for a clicked item, but I am not sure if I can do that without putting it in the URL.
Right now it is done like this:
In my .html for each item in the table:
view more</td>
In my urls.py
url(r'^track/(?P<title>.+?)/$', detail,
name='detail'),
In my detail view, where it uses the variable:
def detail(request, title):
if request.method == 'GET':
...
Now this might work, but it is not ideal for me. The url contains whitespace and is not urlencoded, because I need the variable like it is. I was wondering if there is some easier, or better way to pass this variable to a different view or template
The right way to do this is to define a get_absolute_url method on the model class for your item model. This is typically done using reverse, so it would look something like this:
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('detail', kwargs={'title': self.title})
Then in your template you simply do:
view more
And the title will be properly escaped.
That said, you might want to consider using a slug instead of a title to generate your URLs.

RESTful api in Django using inbult view in Django, without creating 2 urls

I've decent experience in Function based view in Django and now I'm trying to use Class based View. although I'm able to solve problems but I'm not sure about standard, I'mean if I'm doing it right or wrong, what you guyz(Django developers) follow.
More details about problem is here-
views.py
from django.views.generic import View
class InvoiceTransaction(View):
def __init__(self):
super(InvoiceTransaction, self).__init__()
#method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(InvoiceTransaction, self).dispatch(*args, **kwargs)
def get(self, request, *args, **kwargs):
invoiceid = kwargs.get('invoiceid')
# here I have invoiceid, which is I'm passing through url paramaeters(see urls.py file)
# based on invoice, I can decide what type of GET requests it is
# whether user is asking for a single resource or all resource, right?
if invoiceid:
invoice = [Invoice.objects.get(id=invoiceid)]
else:
invoice = Invoice.objects.all()
def post(self, request, *args, **kwargs):
# some stuff
urls.py
from django.conf.urls import patterns, url
from invoice import views
urlpatterns = patterns('',
(r'^invoices/$', views.InvoiceTransaction.as_view()),
(r'^invoices/(?P<invoiceid>.*)/$', views.InvoiceTransaction.as_view()),
)
I followed this tutorial https://realpython.com/blog/python/django-rest-framework-class-based-views/
So my problem is that I'm creating two lines(urls) in urls.py file for a single request to determine the type of GET request. is there any other or better way to do this. how can I create a restful api using view and without creating 2 urls.
PS: feel free to suggest improvement/changes in above code as I'm newbie to this thing. it could be if I'm using dispatch method wrongly or idont really need init method, anything you suggest.
Try this pattern, this should work for both urls -
urlpatterns = patterns('',
(r'^invoices(/(?P<invoiceid>\d+)){,1}/$', views.InvoiceTransaction.as_view()),
)
This makes the whole id block optional but only one can be there at most.
BTW, .* is not quite right for id, better to use \d+
You can verify at pythex.org.
EDIT: with ^invoice(/(?P<invoice_type>.*)){,1}/$
You just have to remove the first pattern and remove the ending slash from the second pattern.
So, your urlpatterns become
urlpatterns = patterns('',
(r'^invoices/(?P<invoiceid>.*)$', views.InvoiceTransaction.as_view()),
)
This is because you are already using .* in the regex instead of .+, invoiceid that you receive can be empty.
But the compulsory end slash in your regex is preventing that from happening. In simpler terms, you already had the solution to your problem.
As REST states that the system must talk only in terms of nouns and verbs.
The verbs that are applicable in a RESTful architecture are:
GET
POST
PUT
PATCH
DELETE
And the 2 urls, that any resource representation for a RESTful system are :
invoice/$
invoice/(?P<pk>\d+)/$
Let's have a look at the View which handles the urls without the pk.Let's call this view InvoiceListCreateView. Now, InvoiceListCreateView should only cater to GET and POST requests. It should not allow PUT, PATCH and DELETE requests. Why?
You can edit/delete only the existing objects and all the existing objects in your db ought to have an id associated with them. So, when I GET the ListCreateView, I get the list of all the Invoices existing in the database. When I POST to the ListCreateView , I should be able to insert a new entry into the Invoice table of the database.
Now, the url with the id appended to it. Let's call it RetrieveUpdateDeleteView. As the name suggests, the view should be able to perform the 3 functions namely, RETRIEVE, UPDATE and DELETE. And all these operations can be performed on the already existing objects for which the id will be present in the url kwargs.
When I GET the RetrieveUpdateDeleteView, I must get the object for that id provided in the url kwargs. Similarly, PUT and PATCH should update the object with the data sent by the user. And DELETE should delete the object from the database.
This is how I plan out the REST architecture.

Custom Add and Edit Template Dextertiy

'I have a package called foo.package. And I also have a content item called mydocument.py. As a standard structure, inside foo/package I have browser, content, profiles, etc. What I want to achieve is to create a customized add template for my content item which is mydocument.
I have read the article from this link http://docs.plone.org/external/plone.app.dexterity/docs/advanced/custom-add-and-edit-forms.html
What I have done is that I created a file inside browser directory and named it as mydocumentaddform.py. Also, inside my browser directory I have templates directory.
The code inside mydocumentaddform.py:
from five import grok
from plone.directives import dexterity, form
from Products.CMFCore.utils import getToolByName
grok.templatedir('templates')
class mydocumentaddform(dexterity.AddForm):
grok.name('foo.package.mydocument')
form.wrap(False)
Inside browser/templates directory I created the template mydocumentaddform.pt. However, my customized mydocumentaddform template was not rendered as I add the mydocument content, since inside the template I added js script to detect whether the customized add template override the default add template. As I view my instance, there is a UserWarning that there is an unassociated template configuration which points to my add template: ~... /foo/package/browser/templates/mydocumentaddform.pt
Is there anyone who have encountered the same problem? Or is there any other way to do this? Thanks.
*Yes I forgot to include the quotes here on grok.name.
Update:
I found a temporary solution, inside the class ViewPageTemplateFile. Here's the updated code:
from five import grok
from plone.directives import dexterity, form
from Products.CMFCore.utils import getToolByName
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
grok.templatedir('templates')
class mydocumentaddform(dexterity.AddForm):
grok.name('foo.package.mydocument')
template = ViewPageTemplateFile('templates/mydocumentaddform.pt')
form.wrap(False)
The customized add template was read, however, still my instance always says that the template that I used is still unassociated. As I also observed, when I replace the base class into dexterity.DisplayForm, the instance error is gone. With this temporary solution, I am not sure of any possible effect in the future due to this persistent error.
I see some issues in your code: you're missing the quotes on the name:
grok.name('foo.package.mydocument')
you need to define the context:
grok.context(IMyDocument)
did you declare an add-on layer? then you need:
grok.layer(IMyLayer)
you can find a working example in collective.nitf.

MultipleHiddenInput renders only if with initial data

class MyForm(forms.Form):
my_hidden_field = forms.MultipleChoiceField(widget=forms.MultipleHiddenInput, choices=(...))
def my_view(request):
form = MyForm(initial={'my_hidden_field': MyModel.objects.values_list('id', flat=True)})
With such code, if remove initial argument from call to MyForm, my_hidden_field will not be rendered in HTML, but if remove MultipleHiddenInput widget then, it will appear again.
How to make it being rendered properly?
This is just the way it is implemented. If you do not pass any values, then there is nothing to render, because it is hidden anyway, so user just cant alter the values.
You can see the implementation here:
https://github.com/django/django/blob/master/django/forms/widgets.py#L316
If you need to render it, you will need to pass some initial data to it, but it is strange, what is the use case exactly ?

Django - using regex in urls.py to pass values

I just ran into a problem..
I'm trying to build a website at the moment with different pages.
So I created a django app called pages, with the following fields:
title
text
URL
The idea is, that users can create new pages and delete existing ones and it actually affects the navigation in real time.
So in my urls.py I wanted to handle this somehow like this:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^pages/(/w)', pages.views.display_content),
)
For example there could be a page with URL property "page1", then "page1" should be stored by (/w) and passed over to pages.views.display_content, which then would display the corresponding data. The "page1" page would be accessible through domain.com/pages/page1.
However, as I'm not really good with regex, I think I really need your help.
I would be really happy if someone could explain to me how I have to write my URL rule for this..
Good Night :)
In addition, you could name the parameter that will be captured and passed to your view function with this notation:
...
(r'^pages/(?P<page_name>\w+)', 'pages.views.display_content'),
...
So you can access it with that name in your view function.
Its header should look like this:
def display_content(request, page_name):
...

Categories

Resources