How to use Django for rendering class based python file? - django

I am trying to learn Django. I have a python program which has class in it. All the examples that use python's class inherits Model.model. My class doesn't require any database. Can anyone help me how to set urls.py in django for this particular case?
What I have done so far is that I have imported the class, and the method inside the class from where I have to display my value. But it is always showing me some error.
This is what I have done in urls.py:
1. from mysite.to_twitter_streaming import StdOutListener
2. url(r'^temp/$', StdOutListener().text_extract)
This StdOutListener is the class and text_extract is the function which has a value that I want to get printed.
I used this for printing:
return render_to_response('TwitterApi.html', {'link': key, 'count':self.counter})
errors that I am getting are:
1. TypeError at /temp/
2. expected string or buffer

ok in your urls.py
Change the format
url(r'^temp/$', text_extract),
I am assuming you have text_extract in your views
In your views.py
def text_extract(request):
# do your stuff
return render_to_response('TwitterApi.html', {'link': key, 'count':self.counter})

Related

In Django, How to get the currently running app from within a model on another app?

Basically i am trying to use .get_absolute_url() to return dynamic links in relative to the current app running, in other words reverse the model url to a different url based on which app being called.
Let me try to explain what i am trying to do by example, We have three apps
Blog (serves as a shared data layer, contains models for post, authors ... etc)
BloggerWay (serves as a view layer number one, uses the Blog app models to display content in some given layout)
TumblrWay (serves as another view layer, again uses the Blog app models to display content in some given layout)
My urls.py files goes like
----------
*Project.urls.py*
----------
urlpatterns= [
url('/blogger/', include(BloggerWay.urls.py, namespace='blogger'),
url('/tumblr/', include(TumblrWay.urls.py, namespace='tumblr'),]
----------
*BloggerWay.urls.py*
----------
urlpatterns= [
url('/post/(?P<id>\d+)', Blog.as_view(), name='blog'),]
----------
*TumblrWay.urls.py*
----------
urlpatterns= [
url('/post/(?P<id>\d+)', Blog.as_view(), name='blog'),]
My question is How can i define .get_absolute_url() method for the Post model so it knows which app we are in and return the correct url to it.
example:
if in BloggerWay return '/blogger/post'
if in TumblrWay return '/tumblr/post'
I know that i can use the reverse() function to get the url for a given named pattern and that it accepts a current_app= argument but my problem is how can i get the running app so i can pass it.
class Post(...):
def get_absolute_url(self):
WhoAmI = ... #get current app here, BUT HOW!
return reverse('post', current_app=WhoAmI)
Solutions that i want to avoid:
I can inherit the Post class in both of the apps, override the .get_absolute_url() there, hardcoding the name space of each app in it. Then use the class in my app instead of directly using the one defined as model/table.(while offcourse avoid performing migrations for that class, even better define it somewhere else than models.py)
Implement another property for get_url() for your class.
The reverse function should includes "namespace:name"
e.g
class Post(...):...
def get_blogger_url(self):
return reverse("blogger:post", kwargs={"id":self.id}) # for Blogger
def get_tumblr_url(self):
return reverse("tumblr:post", kwargs={"id":self.id}) # for Tumblr

How can I avoid repeating this common code in Django views?

I have many similar functions in my Django views.py that start off like this:
#login_required
def processMyObject(request, myObjectID, myObjectSlug=None):
logger.info("In processMyObject(myObjectID=%s, myObjectSlug=%s)" % (myObjectID, myObjectSlug))
try:
myObject = MyObject.objects.get(id=myObjectID)
except:
logger.error("Failed to get MyObject Object by ID")
raise "Failed to get MyObject Object by ID"
if myObjectSlug != None and myObject.slug != myObjectSlug:
logger.error("myObjectSlug '%s' doesn't match myObject #%s's slug" % (myObjectSlug, myObject.id))
raise "myObjectSlug '%s' doesn't match myObject #%s's slug" % (myObjectSlug, myObject.id)
Each of these functions has the same argument signature and contains the same chunk of code at the top, but then goes on to do implement some unique functionality. However this is common code in each one of them. It seems like a horrible violation of DRY for me to have typed the same code so many multiple times.
How can I use inheritance or some other technique to elegantly factor out this code so that it only appears once but is used in each of these view functions?
You can write decorator that recieves the MyObjectId and slug from view as parameter. logs the info line and raises an error if object is missing.
Just check information about function decorators and read django code for examples. For example, look up the code for the decorator you are already using (login_required) and look up the user_passes_test decorator in django.contrib.auth.decorators. That is probably the best real example for your case.
And then use the decorator in front of each view that needs it - just like you are using #login_required

String from Django template, but without returning a HTTPResponse

I have a query set whose objects I'd like to use to populate a template. One view I have ends with
return render_to_response('entry.json', {'entry_list':r}, mimetype="application/json; charset=utf-8")
However I'd like to be able to serialise to json with a template like this without having to return a HTTPResponse. In pseudocode, this might be:
render('entry.json', {'entry_list':r}) #returns a string with the template entry.json
Is this possible? If so, how?
What #HankGay said is correct, though you sometimes might want to get the template response with out returning a HttpResponse, even though you are using Django correctly.
read this: Rendering a context:
>>> from django.template import Context, Template
>>> t = Template("My name is {{ my_name }}.")
>>> c = Context({"my_name": "Adrian"})
>>> t.render(c)
"My name is Adrian."
>>> c = Context({"my_name": "Dolores"})
>>> t.render(c)
"My name is Dolores."
Is that what you're after?
Django provides a built in shortcut for this.
https://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-string-shortcut
I don't quite understand what you are trying to accomplish, But you can just return JSON as your HTTPResponse. You can serialize objects to jason and return it without the use of any template.
If you aren't handling HTTP requests, it doesn't make much sense to use Django, honestly. Look into Jinja 2 for a simple template engine that has lots in common w/ Django's, and SQLAlchemy for an ORM that is equal or better than Django's.

django settings variables get lost in while being passed to templates

i have a weird problem.
Basically, in my settings.py file i have 4 variables
URL_MAIN = 'http://www.mysite'
URL_JOBS = 'http://jobs.mysite'
URL_CARS = 'http://cars.mysite'
URL_HOMES = 'http://homes.mysite'
In my views.py i have the usual:
from settings import *
I have 6 views calling them and just returning them to templates inside the context:
class CarsHp(TemplateView):
...
class JobsHp(TemplateView):
...
class HomesHp(TemplateView):
...
class CarsList(TemplateView):
...
class JobsList(TemplateView):
...
class HomesList(TemplateView):
...
which are being called in urls by
CarsList.as_view()
...
All of those views have the same statement:
context['URL_MAIN'] = URL_MAIN
...
for all 4 variables.
In templates i'm correctly getting all 4 of them, except for URL_MAIN, which "gets lost" in 2 of those 6 views. I'm accessing them with classical {{ URL_MAIN }} and i've been trying everything, from moving to renaming, but still that URL_MAIN doesn't show up (i get empty string, no errors of sort) after being served from 2 of those views. All the functions basically share the same code (except for the querying and data processing part) and those settings' variables are just being assigned and returned off. Not any sort of check nor modification. I've been trying with django's shell, and i could always retrieve them.
We're being served by apache, with some proxypassing configurations for the robots.txt file and static files. Nothing "serious".
I'm not posting all the 6 views source codes just because they're long and the relevant parts are all described above. But i can post them if you want,i just don't know if it is actually useful since i've been triple checking all the sources for clashing on names or double declarations or incorrect use.
Thanks all in advance, this is really stunning my brain
Ideally, you should use template context processors for this. It will cut down your code and allow you to see exactly where the problem is.
Make a file in your projects called urls_context_processor.py (or similar) and put your variables in there:
def common_urls(request):
return {
'URL_MAIN': "http://...",
'URL_JOBS': "http://...",
'URL_CARS': "http://...",
'URL_HOME': "http://...",
}
and in your settings.py
TEMPLATE_CONTEXT_PROCESSORS = = (
....
'my_project.urls_context_processor.common_urls',)
now the urls variables will be automatically available in all your template, and you won't need to hard code them into every view.

how show personalized error with get_object_or_404

I would like to know how to show personalized errors with the get_object_or_404 method. I don't want the normal Http404 pages, but I want to display a custom message with the message: the result is none.
Thanks :)
The get_object_or_404() is essentially a simple 5-line function. Unless you have some specific reason for using it, just do:
try:
instance = YourModel.objects.get(pk=something)
except YourModel.DoesNotExist:
return render_to_response('a_template_with_your_error_message.html')
If for whatever reason you have to use get_object_or_404(), you can try putting it in a try: ... except Http404: ... block, but I honestly can't think of a plausible reason for that.
As stated by michael, when using get_object_or_404 you cannot customize the message given on http 404. The message provided in DEBUG does offer information about the exception however: "No MyModel matches the given query."
Check out the doc on this. There are three arguments: Model, *args, and **kwargs. The last two are used to build an argument for either get() or filter() on the Model.
The reason I wrote, however, is to address the question of why we would want to use a helper function such as get_object_or_404() instead of, for example, catching it with an exception like Model.DoesNotExist.
The later solution couples the view layer to the model layer. In an effort to relax this coupling we can take advantage of the controlled coupling offered in the django.shortcuts module[1].
And why exactly aren't you using your server's capeability to do just that?
get_object_or_404() is redirecting to the default 404 page right?
If you are on debug mode you won't see it but when deployed django will just refer to the server's 404 html page.
That can't be done with that shortcut. It will only raise a Http404 exception. Your best bet is a try catch if you want full control. Eg.
try:
obj = Model.objects.get(pk = foo)
except:
return HttpResponseRedirect('/no/foo/for/you')
#or
return render_to_response ...