0

Now my code is like:

def use_item(request):
    itemname = request.get('value')
    if itemname == 'item1':
        #do something
    if itemname == 'item2':
        #do something else

Can I do it in the following way?

views.py

class use_item():
    def use_item(self,request):
        itemname = request.get('value')
        use = getattr(self,itemname) # say itemname is 'item1'
        use()

    def item1(self,request):
        #do something

    def item2(self,request):
        #do something else

I've tried the second method but it seems that I was not doing it right. And the reason I want to do it in this way is that I hope to group the methods that they'd be more organized.

the actual code

#views.py
class use_item():
    def useitem(self,request):
        itemname = request.POST.get('value') 
        use = getattr(self,itemname)
        use()
    def jelly(self,request,topic_id):
        t = topic.objects.get(id=topic_id)
        t.top = True
        t.time_topped = datetime.datetime.now()
        t.save()

#urls.py
    url(r'^use/item/(?P<topic_id>\d+)/$', 'use_item.use_item', name='use_item'),
3
  • 4
    What is self at class use_item(self):? You might want to re-visit how to create Python classes Commented Jan 19, 2017 at 4:41
  • Class-based views Commented Jan 19, 2017 at 4:48
  • Please provide your expected output and what you are getting(maybe a wrong output or an error message). Commented Jan 19, 2017 at 5:20

3 Answers 3

1

If you want to have a better organization of your code, and reuse some code accross different views, instead of pasting it where you need, you may use the Django class based views:

# views.py
from django.views import View

class use_item(View):

    def get(self, request, *args, **kwargs):
        itemname = request.POST.get('value')
        use = getattr(self,itemname)
        use()

    def item1(self,request):
        #do something

    def item2(self,request):
        #do something else

# urls.py
from package.views import use_item

urlpatterns = [
    # [...]
    url(r'^use/item/(?P<topic_id>\d+)/$', use_item.as_view(), name='use_item'),
    # [...]
]

But, if at some point you need to call item1() or item2() from another view (is it the reason you mentioned the other view jelly ?), you will see that it is not possible.

One solution could be moving the common methods in another class and make sure your views inherit it. This is often called mixins in django world.

# views.py
from django.views import View

class ItemsRelatedLMixin:
    def item1(self, request):
        #do something

    def item2(self, request):
        #do something else

class use_item(ItemsRelatedLMixin, View):

    def get(self, request, *args, **kwargs):
        itemname = request.POST.get('value')
        use = getattr(self,itemname)
        use()

class jelly(ItemsRelatedLMixin, View):

    def get(self, request, topic_id):
        t = topic.objects.get(id=topic_id)
        t.top = True
        t.time_topped = datetime.datetime.now()
        t.save()

Now, your views jelly and use_item call the common methods. Of course you can define new methods in a view to make them available only from that view. You could also create class members to store values you use often etc. Keep in mind that each request received by Django will trigger creation of a new instance of your view class (you can't keep data stored between 2 requests in class members).

Sign up to request clarification or add additional context in comments.

Comments

1

In Django, view functions are usually organized in modules and not in classes.

To keep things organized, use more than one views module: views.py, foo_views.py, bar_views.py, or: views/__init__.py, views/foo.py, views/bar.py.

Comments

0

You need to provide the view in the signature of the class. i.e.:

from django.views import [your_View_name] 

Then provide the same view in class definition;

class use_item(your_View_name):
    def useitem(self,request):
        itemname = request.POST.get('value') 
        use = getattr(self,itemname)
        use()

If you are defining your class for the same view,

class use_item(self):
    def useitem(self,request):
        itemname = request.POST.get('value') 
        use = getattr(self,itemname)
        use()

You may refer Django docs on Class-Based-View for more in-depth knowledge.

UPDATE:

When you are calling your function useitem you need to use the instance of your class as follows:

user_instance = views.use_item()       //Create instance of your class
user_instance.useritem()               //call your function using above instance 

4 Comments

TypeError: unbound method useitem() must be called with use_item instance as first argument (got nothing instead) [19/Jan/2017 19:43:52]"GET / HTTP/1.1" 500 59
I think this error means that I have to instantiate the class before I call the method. But how to do that in django?
@ming Updated my answer. Hope that clarifies your query.
@DhavalSimaria your example code has some indentation issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.