'CustomUser' object is not iterable - django

I am trying to establish a user type base register/login system for my e-commerce app. I have used the following codes in my views file. here's the code snippet from my models.py. Just given the customer class as i am focusing on that first.
class CustomUser(AbstractUser):
user_type_choices=((1,"Merchant"),(2,"Customer"))
user_type=models.CharField(max_length=255,choices=user_type_choices,default=1)
class Meta(AbstractUser.Meta):
swappable = "AUTH_USER_MODEL"
class CustomerUser(models.Model):
auth_user_id=models.OneToOneField(CustomUser,on_delete=models.CASCADE)
user=models.OneToOneField(CustomUser,on_delete=models.CASCADE, related_name='customer', null= True,blank=True)
name= models.CharField(max_length = 255, null= True)
firstname = models.CharField(max_length = 255, null=True)
lastname = models.CharField(max_length = 255, null=True)
email = models.CharField(max_length = 255, null=True)
profile_pic=models.FileField(default="")
created_at=models.DateTimeField(auto_now_add=True)
So, as far I can say that I am logged in but can't access my home page as I got the following error.
TypeError at /
'CustomUser' object is not iterable
.......
Local vars
F:\rewards\projectreward\rewardapp\userviews.py, line 152, in store
data = cartData(request) …
Local vars
F:\rewards\projectreward\rewardapp\utils.py, line 43, in cartData
order, created = Order.objects.get_or_create(request.user, complete=False) …
I'm not sure why my cartData function in utlis.py is affected by this. It worked perfect when I didn't used user type base login. However, here's the cartData from utils.py.
def cartData(request):
if request.user.is_authenticated:
order, created = Order.objects.get_or_create(request.user, complete=False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
else:
cookieData = cookieCart(request)
cartItems = cookieData['cartItems']
order = cookieData['order']
items = cookieData['items']
return {'cartItems': cartItems, 'order': order, 'items':items}
my forms.py is:
class CustomerSignUpForm(UserCreationForm):
mob = forms.IntegerField(min_value = 0, max_value = 9000000000000)
first = forms.CharField(max_length = 255)
last = forms.CharField(max_length = 255)
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ['first', 'last' ,'username', 'email', 'password1', 'password2', 'mob']
lastly the views for registration and login is as follows:
def customerSignUpView(request):
form_class = CustomerSignUpForm
if request.method == 'POST':
form = CustomerSignUpForm(request.POST)
if form.is_valid():
user = form.save()
user.save()
user = authenticate(username=user.username, password=user.password)
return redirect('login')
else:
form = form_class()
return render(request, 'usertemplates/register.html', {'form': form})
def loginUser(request):
page = 'login'
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('store')
else:
messages.warning(request, "Invalid Credentials")
return redirect('login')
return render(request, 'usertemplates/login.html', {'page': page})

Doesn't get_or_create() use kwargs? In which case you'll need something like
order, created = Order.objects.get_or_create(customer=request.user, complete=False)
where 'customer' is the name of the user foreign key field in the Order model.
Edit based on comment below
customer_user = CustomerUser.objects.get(user = request.user)
order, created = Order.objects.get_or_create(customer=customer_user, complete=False)

Related

How to fix Cannot assign "": "" must be a "" instance? when FK model is created?

I want to create model with view when the user is created, but I got and error:
Cannot assign "<User:test1234": "Customer_info.customer" must be a "Customer" instance.
Here are the models that I have and which I want to be created automatically when user is registered.
class Customer(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
points = models.FloatField(default = 0.0)
...
class Customer_info(models.Model):
customer = models.OneToOneField(Customer, on_delete=models.CASCADE)
deposit = models.FloatField(default = 0.0)
And in views.py after registering those models are creating
def reg(request):
form = CreateUserForm()
if "register-btn" in request.POST:
form = CreateUserForm(request.POST)
if form.is_valid():
new_user = form.save()
login(request, new_user)
Customer.objects.create(
user=new_user, points=0.0
)
Customer_info.objects.create(
customer = new_user, deposit = 0.0
# HERE IS THE PROBLEM, IN THE customer field
)
response = redirect('profile')
return response
return render(request, 'main.html')
As the error stats, you are assigning a User instance to a customer field which has a foreignkey relation to Customer
Your logic should look like this:
def reg(request):
form = CreateUserForm()
if "register-btn" in request.POST:
form = CreateUserForm(request.POST)
if form.is_valid():
new_user = form.save()
login(request, new_user)
# store the new customer in a variable
customer = Customer.objects.create(
user=new_user, points=0.0
)
Customer_info.objects.create(
# assign it to `customer` field
customer = customer, deposit = 0.0
)
response = redirect('profile')
return response
return render(request, 'main.html')

Django form : Setting the user to logged in user

I am trying to create an address book website where logged in user is able to fill in a form and store contact information. I was able to implement the login and logout functionality. But the problem is that I am not able to set the username to current logged in user. Here is what I have implemented so far:
Models.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
#additional
def __str__(self):
return self.user.usernname
class UserContacts(models.Model):
current_user = models.ForeignKey(User,on_delete=models.CASCADE)
first_name = models.CharField(max_length = 150)
last_name = models.CharField(max_length = 150)
phone_number = models.CharField(max_length = 150)
email_address = models.CharField(max_length = 150)
street_address = models.CharField(max_length = 350)
def __str__(self):
return '{}'.format(self.first_name)
Forms.py
class UserForm(forms.ModelForm):
password = forms.CharField(widget = forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
class UserContactForm(forms.ModelForm):
class Meta():
model = UserContacts
fields = "__all__"
views.py:
#login_required
def new_contact(request):
form = UserContactForm()
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()
if request.method == "POST":
form = UserContactForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print('Error Form Invalid')
return render(request,'basic_app/contact.html',{'form':form})
Here is how the output looks like when the logged in user tries to enter contact information details:
Updating contact screenshot. As you can see the current user has to select his username to fill out the contact information.
How to overcome this and by default set the username in the form to the current logged in user
Change your UserContactForm to include an extra perameter in __init__, and set the initial value on the user field:
class UserContactForm(forms.ModelForm):
class Meta():
model = UserContacts
fields = "__all__"
def __init__(self, *args, **kws):
# To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
self.user = kws.pop('user')
super().__init__(*args, **kws)
self.fields['user'].initial = self.user
Then change you view to add in the request.user to the form construction:
#login_required
def new_contact(request):
form = UserContactForm(user=request.user)
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()
if request.method == "POST":
form = UserContactForm(request.POST, user=request.user)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
print('Error Form Invalid')
return render(request,'basic_app/contact.html',{'form':form})
You could probably remove the:
current_user = request.user.get_username()
user = User.objects.filter(username=current_user).first()
output = UserContacts.objects.filter(current_user_id=user.id).first()

Need to search user based on email and then deactivate his profile

I am trying to create a search form, Where admin can search users and then deactivate their profiles, if it is the right account.
tried function based views and then class based views. It shows the profile in function based views but doesn't update it. and in class based view it wouldn't even show the profile.
models.py
class User(AbstractBaseUser):
objects = UserManager()
email = models.EmailField(verbose_name='email address', max_length=255, unique=True,)
type = models.CharField(max_length = 50, choices = type_choices)
name = models.CharField(max_length = 100)
department = models.CharField(max_length = 100, null = True, blank = True, choices = department_choices)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a superuser
admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['type']
forms.py
class SearchForm(forms.Form):
email = forms.EmailField(required=True)
views.py
#method_decorator(login_required, name='dispatch')
class adminDeleteProfileView(LoginRequiredMixin, View):
def render(self, request):
return render(request, 'admin/view_account.html', {'form': self.form})
def form_valid(self, form):
self.form = SearchForm(request.POST)
print('im here', form.cleaned_data.get('email'))
User.objects.filter(email = form.cleaned_data.get('email')).update(active = False)
#print('Donot come here')
def get(self, request):
self.form = SearchForm()
return self.render(request)
#login_required
def admin_deactivate_profile_view(request):
error_text = ''
if request.method == 'POST':
print('here')
user_email = request.POST.get('email')
try:
print('Deactivating',user_email, 'Account.')
profile = User.objects.filter(email = user_email).first()
if request.POST.get('delete'):
User.objects.filter(email = user_email).update(active = False)
messages.success(self.request, 'Profile Updated!')
except Exception as e:
print(e)
messages.success(self.request, 'There was an error!')
return render(request, "admin/delete_profile.html", {'profile':profile})
simple query .
user=User.objects.get(email="user#email.com")
user.activate=false
user.save()

Key Error with form - DJANGO

I have a project in django and I am creating a simple form that will allow a user to create a simple profile that asks for name and date of birth and location. I am getting a key error with the date of birth section and I dont know exactly why.
I am trying to collect data and store it to then later added it to a database record.
Here is the views file:
cd = form.cleaned_data
first_name = cd['first_name']
last_name = cd['last_name']
dob_month = cd['dob_month']
dob_day = ['dob_day']
dob_year = ['dob_year']
city = cd['city']
state = cd['state']
phone = cd['phone']
privacy = cd['privacy']
Here is the models file:
user = models.ForeignKey(User, on_delete=models.CASCADE) # server
first_name = models.CharField(max_length=25, default='first')
last_name = models.CharField(max_length=25, default='last')
dob_month = models.IntegerField(default=0)
dob_day = models.IntegerField(default=0)
dob_year = models.IntegerField(default=0)
city = models.CharField(max_length=45) # user
state = models.CharField(max_length=25, default='state')
phone = models.BigIntegerField(default=0) # user
privacy = models.SmallIntegerField(default=1) # user
created = models.DateTimeField(auto_now_add=True) # server
here is the forms file:
class ProfileForm(forms.ModelForm):
split_choices = (('1', 'public'),
('2', 'private'))
privacy = forms.TypedChoiceField(
choices=split_choices, widget=forms.RadioSelect, coerce=int
)
dob = forms.DateField(widget=extras.SelectDateWidget)
class Meta:
model = Profile
fields = ['first_name', 'last_name', 'dob', 'city', 'state', 'phone', 'privacy']
and finally, here is the error that I am getting:
KeyError at /setup_profile/
'dob_month'
Request Method: POST
Request URL: http://127.0.0.1:8000/setup_profile/
Django Version: 1.8.6
Exception Type: KeyError
Exception Value:
'dob_month'
Exception Location: C:\Users\OmarJandali\Desktop\opentab\opentab\tab\views.py in profile_setup, line 292
first_name 'omar'
last_name 'jandali'
dob_month '1'
dob_day '23'
dob_year '2024'
city 'riverside'
state 'ca'
phone '9515343666'
privacy '1'
submit 'submit'
UPDATED:
here is the views.py file but the issue is with the cd['dobv_month'], but i have no idea why the error is coming from there.
def profile_setup(request):
if 'username' not in request.session:
return redirect('login')
else:
# the following is just going to grab the currently logged in user and
# save the profile information to the appropriate user
username = request.session['username']
currentUser = User.objects.get(username = username)
# the following is the provessing for the form where the user entered
# the profile informaiton
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
first_name = cd['first_name']
last_name = cd['last_name']
dob_month = cd['dob_month']
dob_day = ['dob_day']
dob_year = ['dob_year']
city = cd['city']
state = cd['state']
phone = cd['phone']
privacy = cd['privacy']
# this is the new record that is going to be created and saved
new_profile = Profile.objects.create(
user = currentUser,
first_name = first_name,
last_name = last_name,
dob_month = dob_month,
dob_day = dob_day,
dob_year = dob_year,
city = city,
state = state,
phone = phone,
privacy = privacy,
)
return redirect('home_page')
else:
# this is what is going to be saved into the html file and used to
# render the file
form = ProfileForm()
message = 'fill out form below'
parameters = {
'form':form,
'currentUser':currentUser,
'message':message,
}
return render(request, 'tabs/profile_setup.html', parameters)
Let's say your model name is User.
forms.py:
from .models import User
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
class Meta:
model = User
fields = '__all__'
and views.py:
def user_create(request):
form = UserForm(request.POST or None)
if request.method == 'POST':
form = UserForm(request.POST or None)
if not form.is_valid():
print form.errors
return render(request, 'user_create.html', {'form': form})
else:
first_name = form.cleaned_data.get("first_name")
last_name = form.cleaned_data.get("last_name")
# pass your extra fields here
new_user = User.objects.create_user(
user=user,
first_name=first_name,
last_name=last_name,
)
new_user.save()
return redirect('where you want to redirect',)
return TemplateResponse(request, 'user_create.html')
finally user will be save.
Read docs:https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/

Registration form save

I try to save two forms in registration. I can see the auth form save but the second form is not pass .is_valid(). Could you please let me know what is wrong?
Models.py
class School(models.Model):
id = models.IntegerField(primary_key=True)
Name = models.CharField(max_length=50, null=False)
Domain = models.CharField(max_length=50, null=False)
Mascot = models.ImageField(null=True, upload_to='mascot')
def delete(self, *args, **kwargs):
self.Mascot.delete()
super(School, self).delete(*args, **kwargs)
def __str__(self):
return self.Name
class HeepooUser(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=15, null=True)
allow_phone = models.BooleanField(default=False)
school_id = models.IntegerField()
date_join = models.DateTimeField(auto_now_add=True)
forms.py
class UserForm(forms.ModelForm):
email = forms.EmailField(max_length=50, required=True)
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('email', 'password')
class RegisterForm(forms.ModelForm):
school_id = forms.ModelChoiceField(queryset=School.objects.all())
phone = forms.CharField(max_length=15, min_length=10, required=False)
class Meta:
model = HeepooUser
fields = ('phone', 'school_id')
views.py
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = RegisterForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save(commit=False)
user.set_password(user.password)
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile = profile_form.save()
registered = True
else:
return HttpResponse('Wrong access1')
else:
user_form = UserForm()
profile_form = RegisterForm()
return render(request, "register.html", {
'user_form': user_form,
'profile_form': profile_form,
'registered': registered,
})
I try to save email and password to auth_user and school_id and phone to separate table.
All the best!
tested your code and what I've encountered when submitting a form is
school_id value must be an integer
I'm suggesting to set school_id/school to be a foreignKey of the School model
class HeepooUser(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=15, null=True)
allow_phone = models.BooleanField(default=False)
school_id = models.ForeignKey(School)
date_join = models.DateTimeField(auto_now_add=True)
so that we could just do the forms like this
class RegisterForm(forms.ModelForm):
class Meta:
model = HeepooUser
exclude = ('allow_phone', 'user')
also I think you don't need to specify the form fields for UserForm since by default django user only requires a password, username, and email
The problem is with how binary ANDs work. If user_form.is_valid() returns False, the "if" statement marks the whole statement as False without needing to evaluate profile_form.is_valid(). Therefore, profile_form.is_valid() never gets called and it's errors dict will not get populated. Unfortunately, django's form is_valid() does more than just return a boolean and has the side effect of populating that errors dict.
if user_form.is_valid() and profile_form.is_valid():
...
One thing you might be able to do is something like this:
user_valid = False
if user_form.is_valid():
user_valid = True
profile_valid = False
if profile_form.is_valid():
profile_valid = True
if user_valid and profile_valid:
... do something
The above ensures that both forms get processed. There might be a better way to express it, but that's the idea.