Getting information from view to template

Here is what the email looks like:

# Hello ,

## Please click the link below to accept sponsorship of None:

### New User Comments:

### [Accept Sponsorship](http://127.0.0.1:8000/accounts/accept_sponsorship/MTM4/bvnkb3-1ae6d7e98bbd650d58a55fca2a4e3b87/)

These variables should be after Hello {alias_name_url }, where None is {new_alias_name}, and blank under user comments {user_comments}

views.py

from .forms import CustomUserCreationForm
from .models import CustomUser
from .tokens import account_activation_token
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import send_mail, EmailMessage
from django.http import HttpResponseBadRequest
from django.shortcuts import render, redirect
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.views.generic.edit import CreateView
import re, random, qrcode, requests


class SignUpView(CreateView):
    form_class = CustomUserCreationForm
    success_url = reverse_lazy("login")
    template_name = "signup.html"
    model = CustomUser

    def form_valid(self, form):
        request_url = form.data['url']
        alias_name_url = str(re.sub(r'/accounts/signup/', '', request_url)).lower()
        an = CustomUser.objects.filter(alias_name=alias_name_url).values('alias_name').exists()
        status = CustomUser.objects.filter(alias_name=alias_name_url).values('status').filter(status='fr').exists()

        if an == True and status == True:
            new_user =form.save()
            user_comments = form.data['user_comments']
            user_id = CustomUser.objects.filter(username=form.cleaned_data['username']).values('id')[0]['id']
            user_email = CustomUser.objects.filter(username=form.cleaned_data['username']).values('email')[0]['email']
            sponsor_id = CustomUser.objects.filter(alias_name=alias_name_url).values('id')[0]['id']
            sponsor_email = CustomUser.objects.filter(id=sponsor_id).values('email')[0]['email']
            sponsor_org_id = CustomUser.objects.filter(alias_name=alias_name_url).values('org_id')[0]['org_id']
            user_upline = CustomUser.objects.filter(alias_name=alias_name_url).values('downline')[0]['downline']
            user_downline = str(user_upline) + "," + str(user_id)
            new_alias_name = str(form.cleaned_data['first_name'] + '_' + form.cleaned_data['last_name'][0] + str(
                random.randrange(0000, 9999))).lower()
            if CustomUser.objects.filter(alias_name=new_alias_name).values('alias_name').exists() == True:
                while CustomUser.objects.filter(alias_name=new_alias_name).values('alias_name').exists() == True:
                    new_alias_name = str(
                        form.cleaned_data['first_name'] + '_' + form.cleaned_data['last_name'][0] + str(
                            random.randrange(0000, 9999))).lower()
                    if CustomUser.objects.filter(alias_name=new_alias_name).values('alias_name').exists() == False:
                        new_alias_name = new_alias_name
                        break
            else:
                new_alias_name = new_alias_name



            alias_email = new_alias_name + 'xxxxxxxxxxxx'

            CustomUser.objects.filter(username=form.cleaned_data['username']).update(is_active=False)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(sponsor=sponsor_id)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(org_id=sponsor_org_id)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(upline=user_upline)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(downline=user_downline)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(alias_name=new_alias_name)
            CustomUser.objects.filter(username=form.cleaned_data['username']).update(alias_email=alias_email)




            current_site = get_current_site(self.request)
            subject = 'Activate your account'
            message = render_to_string('account_activation_email.html', {
                'user': new_user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
                'token': account_activation_token.make_token(new_user),
            })

            send_mail(subject, message, 'xxxxxxxxxxxxxxxxxxxx', [user_email], html_message=message)


            current_site = get_current_site(self.request)
            subject = 'Accept new user'
            message = render_to_string('accept_sponsorship_email.html', {
                'user': new_user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
                'token': account_activation_token.make_token(new_user),
                'user_comments': user_comments,
            })

            send_mail(subject, message, 'xxxxxxxxxx', [sponsor_email], html_message=message,)


            return redirect('account_activation_sent')


        elif an == True and status == False:
            return render(self.request, 'is_fish.html')
        else:
            return render(self.request, 'bad_alias.html')


def account_activation_sent(request):
    return render(request, 'account_activation_sent.html')


def activate(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = CustomUser.objects.get(pk=uid)

    except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        login(request, user)
        return redirect('account_activation_complete')
    else:
        return HttpResponseBadRequest('Activation link is invalid!')

def account_activation_complete(request):
    return render(request, 'account_activation_complete.html') 


##################################################################################################

def accept_sponsorship(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = CustomUser.objects.get(pk=uid)

    except (TypeError, ValueError, OverflowError, CustomUser.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.sponsor_accept = True
        user.save()
        return redirect('accept_sponsorship_complete')
    else:
        return HttpResponseBadRequest('Accept Sponsorship link is invalid!')
    
def accept_sponsorship_complete(request):
    return render(request, 'accept_sponsorship_complete.html') 

What is the template being rendered?

Which view should we be looking at?

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Hello {{ alias_name_url }},</h1>
    <h2>Please click the link below to accept sponsorship of {{ user.alias_name }}:</h2>
    <h3>New User Comments:</h3><br>
    {{user.user_comments}}
    <h3><a href="http://{{ domain }}{% url 'accept_sponsorship' uidb64=uid token=token %}">Accept Sponsorship</a></h3>


</body>
</html>

accept_sponsorship_email.html

First thing to do is to rewrite your form_valid method in SignUpView to account for the information provided to you at base64 user ID object error for email activation - #8 by KenWhitesell

This includes eliminating the roughly 20 useless queries that you have written in it. (Almost every instance you have of CustomUser.objects.filter(...) is unnecessary.) Issue one query to retrieve the object, then use it as needed throughout the view.

Also, it will be helpful if you posted your CustomUser model as that appears to play a key part in this, along with your CustomUserCreationForm.

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.dispatch import receiver
from django.db.models.signals import post_save


class Organization(models.Model):
    org_name = models.CharField(max_length=50)
    org_owner = models.CharField(max_length=20)
    org_admin = models.CharField(list, max_length=100)
    org_crew = models.CharField(list, max_length=100)
    org_img = models.ImageField(upload_to='images/org')
    org_agreement = models.BooleanField(default=False)
    m28t_approved = models.BooleanField(default=False)

    def __str__(self):
        return self.org_name

#
class CustomUser(AbstractUser):
    alias_name = models.CharField(max_length=20, unique=True, null=True, blank=True)
    sponsor = models.BigIntegerField(default=1)
    alias_email = models.EmailField(null=True, blank=True)
    cell = models.CharField(blank=True, max_length=10, help_text='Cell phone number (numbers only)')
    agreement = models.BooleanField(default=False)
    upline = models.CharField(tuple, max_length=1000000, default=1)
    downline = models.CharField(tuple, max_length=1000000, default=1)
    fish_qr = models.ImageField(upload_to='images/qrcodes')
    sponsor_accept = models.BooleanField(default=False, null=True, blank=True)
    email_confirmed = models.BooleanField(default=False)
    org = models.ForeignKey(Organization, on_delete=models.SET_NULL, null=True)

    Status = (
        ('f', 'Fish'),
        ('fr', 'Fisher'),
    )

    status = models.CharField(max_length=2, choices=Status, default='f')

    class Meta:
        ordering = ['alias_name', 'org', 'username', 'email', 'cell', 'sponsor'] 


    def __str__(self):
        return f'{self.alias_name}, {self.org}, {self.username}, {self.email}, {self.cell}, {self.sponsor}' 



@receiver(post_save, sender=CustomUser)
def default_to_non_active(sender, instance, created, **kwargs):
    if created:
        instance.groups.add(1)
        instance.save()
        

forms.py

from .models import CustomUser
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserChangeForm.Meta):
        model = CustomUser
        fields = (
                "first_name",
                 "last_name",
                 "email", 
                 "cell",
                 "username", 
                 'password1', 
                 'password2',
                 )
        

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = (
                "first_name", 
                "last_name", 
                "username", 
                "email", 
                "cell",
                )

So, to specifically address the issues with your template being rendered, the data that you are trying to render in the template is not present in the objects that you are passing through the context.

You’re getting the new_user instance upon saving the form, but then you’re setting values for alias_name and user_comments directly to the database and not modifying the new_user instance.

Also, what does the template look like where you are rendering CustomUserCreationForm?

Disregard - I got it.

As for the queries, I am assuming you mean to write one query that I can then call a query.field?

If so, how would you write that?

The form.save() method returns an instance of the model being saved. You then work with that instance the same way you work with any other instance of any other object.

Cleaned up the queries and added context. Getting a render_to_string() got multiple values for argument ‘context’

Template

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Hello {{ sponsor_name }},</h1>
    <h2>Please click the link below to accept sponsorship of {{ user_name }}:</h2>
    <h3>New User Comments:</h3><br>
    {{user_comments}}
    <h3><a href="http://{{ domain }}{% url 'accept_sponsorship' uidb64=uid token=token %}">Accept Sponsorship</a></h3>


</body>
</html>

context view

       context= {
            'sponsor_name': sponsor_info.alias_name,
            'user_name': user_info.alias_name,
            'comments': user_comments,
        }
        current_site = get_current_site(self.request)
        subject = 'Accept new user'
        message = render_to_string('accept_sponsorship_email.html', {
            'user': new_user,
            'domain': current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(new_user.id)),
            'token': account_activation_token.make_token(new_user),
        }, context=context)

        send_mail(subject, message, 'xxxxxxxxxxxx', [sponsor_info.email], html_message=message,)

I think I figured it out. Will let you know.

Yep it is working. Thanks much!

1 Like