1

i want to call class based index view in function view i render the index template in login function view but when i add a extra context in index template which i do from function views ' it only render's extra context not the one which is already rendered by class based index view.

so i thought if i could call class based index view from function so that i add extra context to class based view and render it at the same time.

in short word's i want to add extra context from function view and render it.

this is my class based generic view for listing object's in index template.

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    title = 'hello'
    num_visit = 'a'
    context_object_name = 'question_list'

    def get_queryset(self):
        """Return the last five published questions."""
           return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]

and this is my login view that render's the same template which class based index view does

def login_view(request):
    user = authenticate(request,username=request.POST['username'],password=request.POST['password'])
    if user is not None:
        login(request, user)
        return redirect('polls:index')
    return render_to_response('polls/index.html', {'error_message': 'wrong credentials'})

.................................................

now i can login in index template but the look at the code context adding does'nt workin maybe it work's but i think it does messes up with default object list context.

class IndexView(generic.ListView):
template_name = 'polls/index.html'
title = 'sdasd'
num_visit = 'a'
context_object_name = 'question_list'
error_message = None

def get_queryset(self):
    """Return the last five published questions."""
    return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]

def post(self, request, **kwargs):
    user = authenticate(request, username=request.POST['username'], password=request.POST['password'])
    if user is not None:
        login(request, user)
        return redirect('polls:index')
    error_message = 'i love jesus'
    context = self.get_context_data(request, error_message, **kwargs)
    return render(request, 'polls:index', context)



def get_context_data(self, *args, **kwargs):
    context = super(IndexView, self).get_context_data(**kwargs)
    context['error_message'] = self.args
    return context

Template code .............. cant add the template code ' it's complicated i added here https://codeshare.io/5zXYJb

trackback error https://ibb.co/jdA7Ek

11
  • Could you please post some code? Commented Jul 25, 2017 at 16:55
  • 1
    You should never call one view from another view. If you have common code in two views, move it to a utility method outside of your views (create a utils.py file) or move it into the model. You should try to move as much logic as possible down towards your models. Commented Jul 25, 2017 at 17:03
  • @IanKirkpatrick i dont think there is another way ' because i want to add login page in same index page where there is also list view is used....... i dont want to use login view for different url in different template ' i hope you understand this is how i want to challenge my self. Commented Jul 25, 2017 at 17:18
  • @IanKirkpatrick you mean login as an model's so that i can use in any views ? Commented Jul 25, 2017 at 17:21
  • So you want a login section on your index page, not a seperate page dedicated just to login? Kind of like Amazons quick login on the top of every page? Commented Jul 25, 2017 at 17:26

1 Answer 1

1

You should not call logic from one view into another. Create a login logic. You didn't post any code so I'm not quite sure how your program works but you could do this:

In forms.py

class MyLoginForm(Form):
    username = forms.TextField(...)
    password = forms.PasswordField(...)

In utils.py

def login(request, user_name, password):
    user = authenticate(request, username=user_name, password=password)
    if user is not None:
        login(request, user)
        return True
    return False

def index_context(...):
    context = {}
    # do context stuff here
    return context

In views.py

class Index(View):
    def post(self, request, *args, **kwargs):
        # The logging_in part is optional but it's used to know when a post request is a login post or for something else. Just add a hidden field in your login form that has this name and a value of True.
        if request.POST.get("logging_in", False):
            authenticated = utils.login(request, request.POST.get("username", ""), request.POST.get("password", ""))

            if authenticated:
                # refresh the page
            else:
                # refresh the page with error
        else:
            # do other POST actions.

    def get(self, request, *args, **kwargs):
        # add a username and password form to context along with whatever other context you need.
        context = utils.index_context(...)
        context["login_form"] = MyLoginForm
        return render(request, "index.html", context)

def login_view(request):
    # Used if you also want a separate login page too.
    if request.method == "POST":
        loggedin = utils.login(request, request.POST.get("username", ""), request.POST.get("password", ""))
        if loggedin:
            return redirect('polls:login')
        return render_to_response('polls/login.html', {'error_message': 'wrong credentials'})
    else:
        # render template with username and password field
        context = {}
        context["login_form"] = MyLoginForm
        return render(request, "login.html", context)

You could also just have a API view that just does login stuff and have ajax call this view. Either way, the actual logic for logging in should be in a separate function that is global.

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

24 Comments

even if i use your code it's look's like it's doing the same thing what my code does ........ how does it suppose to render the data from index view which is list of object's ....... what i wanted was to add extra context from my simple login view to generic list view and render both from login view so that both context will be render in index template at the same time.
I just edited the answer. Note the new method in utils.py
i used post method in class based list view ' it's working fine but second thing i want to do with it is..... in my class based list view ' there are some object list which is rendered automatically by django , and the only way to add extra context is the using get_context_method. what i did was i used get context method in post method and added a new variable then i render and what error i got was 'IndexView' object has no attribute 'object_list' seem's like when i add extra context and render context in post method it throws error.
Can I see your entire view? both views?
how do i add code here ? it wont let me add more than 15 character's
|

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.