How to link guest and user checkout together? - python

I'm very new to Django and I'm confused with the checkout. I have the "accounts" app for the user to enter their profile and I want to link it with the checkout but also include guest checkout. Right now I'm good to the guest-checkout but I cant link the user info from "accounts" app to the checkout.
The is the error I am getting:
IntegrityError at /usercheckout/
NOT NULL constraint failed: accounts_profile.user_id "
accounts/models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=255, default='')
last_name = models.CharField(max_length=255, default='')
email = models.EmailField(default='none#email.com')
birth_date = models.DateField(default='1999-12-31')
address = models.TextField(default='')
mobile = models.CharField(max_length=255, default='')
def __str__(self):
return self.user.username
def __str__(self):
return 'Order {}'.format(self.id)
def create_profile(sender, **kwargs):
if kwargs['created']:
profile = Profile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
orders/models.py
class Order(models.Model):
first_name = models.CharField(max_length=60)
last_name = models.CharField(max_length=60)
email = models.EmailField()
address = models.CharField(max_length=150)
postal_code = models.CharField(max_length=30)
city = models.CharField(max_length=100)
mobile = models.IntegerField(default=0)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
class Meta:
ordering = ('-created', )
def __str__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
orderu = models.OneToOneField(Profile, on_delete=models.CASCADE)
product = models.ForeignKey(Product_info, related_name='order_items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __str__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price * self.quantity
orders/views.py
def guestcheckout(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save()
for item in cart:
OrderItem.objects.create(
order=order,
product=item['product'],
price=item['price'],
quantity=item['quantity']
)
cart.clear()
return render(request, 'order/created.html', {'order': order})
else:
form = OrderCreateForm()
return render(request, 'order/create.html', {'form': form,"cart":cart})
def choose_checkout(request):
return render(request,'order/chooserequest.html',)
#login_required
def usercheckout(request):
cart = Cart(request)
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
order = form.save()
for item in cart:
OrderItem.objects.create(
orderu=order,
product=item['product'],
price=item['price'],
quantity=item['quantity']
)
cart.clear()
return render(request, 'order/created.html',{'order': order})
else:
user = request.user
profile = get_object_or_404(Profile, user=user)
form = ProfileForm(instance=profile)
return render(request, 'order/usercheckoutnormal.html', {'form': form,"cart":cart})

Its because your OneToOneField of user is null. Set a user before saving the form, let say -
#login_required
def usercheckout(request):
cart = Cart(request)
user = request.user
profile = get_object_or_404(Profile, user=user)
if request.method == 'POST':
form = ProfileForm(request.POST,instance=profile)
if form.is_valid():
order = form.save()
for item in cart:
OrderItem.objects.create(
orderu=order,
product=item['product'],
price=item['price'],
quantity=item['quantity']
)
cart.clear()
return render(request, 'order/created.html',{'order': order})
else:
form = ProfileForm(instance=profile)
return render(request, 'order/usercheckoutnormal.html', {'form': form,"cart":cart})

Related

can not update data in Django Form

I am not able to upload data in Profile.
How to Solve the problem?
models.py:
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE, blank=True, null=True)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
created_at = models.DateField(auto_now_add=True)
alamat = models.CharField(max_length=200, null=True)
no_tlp = models.IntegerField(default=0)
wilayah = models.CharField(max_length=200, null=True)
j_kel = models.CharField(max_length=200, null=True)
pic_Profile = models.ImageField(upload_to='profil/',default="person-circle.svg",null=True, blank=True)
def __str__(self):
return str(self.id)
forms.py:
class Uplaoddata(ModelForm):
no_tlp = forms.CharField(label='No Telpon', max_length=100)
wilayah = forms.ChoiceField(label =("Wilayah"),widget=forms.Select, choices=wilayah ,help_text="<style>.errorlist{display:None} </style>")
j_kel = forms.ChoiceField(label = ("Jenis Kelamin"),widget=forms.Select, choices=Jenis ,help_text="<style>.errorlist{display:None} </style>")
pic_Profile = forms.ImageField(label='Foto Profil', max_length=100)
class Meta:
model=Profile
fields=["email", "name", "alamat", "no_tlp", "wilayah", "j_kel", "pic_Profile"]
views.py:
def home(request):
data = cartData(request)
cartItems = data['cartItems']
id_profil = request.user.profile
profiles = Profile.objects.get(id__contains=id_profil)
if request.method == "POST":
form = Uplaoddata(request.POST ,request.FILES, instance=profiles)
if form.is_valid():
form.save()
else:
form=Uplaoddata(instance=profiles)
print("Data Tidak terupdate")
context = {'profiles':profiles,'form':form, 'cartItems':cartItems}
return render(request, 'home.html',context)
Ok, probably you should remove instance=profiles inside the if statement.
def home(request):
data = cartData(request)
cartItems = data['cartItems']
id_profil = request.user.profile
profiles = Profile.objects.get(id__contains=id_profil)
if request.method == "POST":
form = Uplaoddata(request.POST ,request.FILES)
if form.is_valid():
form.save()
else:
form=Uplaoddata(instance=profiles)
print("Data Tidak terupdate")
context = {'profiles':profiles,'form':form, 'cartItems':cartItems}
return render(request, 'home.html',context)

How to assign a default choice value to a user when they sign up in django framework

I am writing a logic where when a users creates and account, i want to automatically assign the free membership to them and i know this should be done in the register view but i don't know why it's not working as expected. I still have to manually go to my admin page and manually assign a value to newly created user and that's not what i really wanted.
Models.py
class Membership(models.Model):
MEMBERSHIP_CHOICES = (
('Enterprise', 'Enterprise'), # Note that they are all capitalize//
('Team', 'Team'),
('Student', 'Student'),
('Free', 'Free')
)
PERIOD_DURATION = (
('Days', 'Days'),
('Week', 'Week'),
('Months', 'Months'),
)
slug = models.SlugField(null=True, blank=True)
membership_type = models.CharField(choices=MEMBERSHIP_CHOICES, default='Free', max_length=30)
duration = models.PositiveIntegerField(default=7)
duration_period = models.CharField(max_length=100, default='Day', choices=PERIOD_DURATION)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
def __str__(self):
return self.membership_type
#### User Membership
class UserMembership(models.Model):
user = models.OneToOneField(User, related_name='user_membership', on_delete=models.CASCADE)
membership = models.ForeignKey(Membership, related_name='user_membership', on_delete=models.SET_NULL, null=True)
reference_code = models.CharField(max_length=100, default='', blank=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=UserMembership)
def create_subscription(sender, instance, *args, **kwargs):
if instance:
Subscription.objects.create(user_membership=instance, expires_in=dt.now().date() + timedelta(days=instance.membership.duration))
views.py
def register(request):
reviews = Review.objects.filter(status='published')
info = Announcements.objects.all()
categories = Category.objects.all()
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
obj = request.user
get_membership = Membership.objects.get(membership_type='Free')
instance = UserMembership.objects.create(user=obj, membership=get_membership)
messages.success(request, f'Account Successfully created for {username}! You can Login In Now')
return redirect('userauths:login')
elif request.user.is_authenticated:
return redirect('elements:home')
else:
form = UserRegisterForm()
context = {
'reviews': reviews,
'form': form,
'info': info,
'categories': categories
}
return render(request, 'userauths/register.html', context)
in models you need to special a default="..." attribute

reset imagefield to default image using if condition django

my profile form has two halves: individual and NGO (ngo part of form has imagefield). the user can switch between the profile types. if user switches from NGO to individual, i update the ngo related fields to NA in my function. However, i need to reset the image field associated with NGO to default and delete the image.
models.py
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
# on_deleting user, profile will also be deleted
image = models.ImageField(default="profilepic.jpg",upload_to="profile_pictures")
profile_type = models.CharField(max_length=20,choices=PROFILE_TYPES, default='individual')
dob = models.DateField(null=True)
bio = models.TextField(null=True)
anonymous = models.BooleanField(default=False)
ngo_name = models.CharField(max_length=200, blank=True)
ngo_address = models.CharField(max_length=200, blank=True)
ngo_phone = models.CharField(max_length=200, blank=True)
ngo_registration_num = models.CharField(max_length=200, blank=True)
ngo_registration_cert = models.ImageField(default="default_ngo.png",upload_to="ngo_documents")
ngo_status = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.user.username} Profile'
forms.py
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image','profile_type','dob','bio','anonymous','profile_type','ngo_name','ngo_address','ngo_phone','ngo_registration_num','ngo_registration_cert','ngo_status']
views.py
#login_required
def profile_edit(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileForm(request.POST, request.FILES, instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
if p_form.cleaned_data.get('profile_type') == 'ngo':
u_form.save()
p_form.save()
messages.success(request, f'your profile has been updated as NGO ')
return redirect('users:profile')
else:
u_form.save()
temp_p_form = p_form.save(commit=False)
temp_p_form.ngo_name = 'NA'
temp_p_form.ngo_address = 'NA'
temp_p_form.ngo_phone = 'NA'
temp_p_form.ngo_registration_num = 'NA'
temp_p_form.ngo_phone = 'NA'
temp_p_form.ngo_status = False
temp_p_form.ngo_registration_cert = NEED TO SET THIS TO DEFAULT IMAGE AGAIN
temp_p_form.save()
messages.success(request, f'your profile has been updated as Individual ')
return redirect('users:profile')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileForm()
context = {
'u_form' : u_form,
'p_form' : p_form
}
return render(request, 'users/profile_edit.html',context)
in your model:
image = models.ImageField(default="profilepic.jpg",upload_to="profile_pictures", blank=True, null=True)
and in view:
temp_p_form.ngo_status = False
temp_p_form.image.delete()
temp_p_form.image = None

Suppress django signal

I have been struggling with this for a couple of weeks now and It seems, I can't get it to work.
As you sign up on my website, you are able to create a userprofile and a company. Then, you are able to add members to your company, however the signal just fires everytime and creates empty companies. How do I stop django from doing this?
model.py
class Companyname(models.Model):
company_name = models.CharField(max_length=100, default = '', null=True, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.TextField(max_length=10000, default = '', null=True, blank=True)
def __str__(self):
return self.company_name
#receiver(post_save, sender=User)
def update_user_company(sender, instance, created, **kwargs):
if created:
Companyname.objects.create(user=instance)
if instance.companyname.company_name is '':
print("just print this")
else:
instance.companyname.save()
the company gets stored on the userprofile
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default = '', null=True, blank=True)
company = models.ForeignKey(Companyname, null=True, on_delete=models.CASCADE)
role = models.ForeignKey(Role, null=True, on_delete=models.CASCADE)
team = models.ForeignKey(Team, null=True, on_delete=models.CASCADE)
company_admin = models.BooleanField(default=False)
add_user view.py
def add_user(request):
if request.method == 'POST':
form = AddUserForm(request.POST)
if form.is_valid():
company = request.user.userprofile.company_id
form.save()
user = form.save()
user.refresh_from_db()
user.userprofile.company_id = company
user.userprofile.role = form.cleaned_data.get('role')
user.is_active = False
user.save()
register view.py
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.userprofile.description = form.cleaned_data.get('description')
user.companyname.company_name = form.cleaned_data.get('company_name')
user.userprofile.company_id = user.companyname.id
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('/account/my_product')
else:
form = RegistrationForm()
return render(request, 'accounts/reg_form.html', {'form': form})
Hope someone can help :)

Django email notification

I want to ask for guidance on how to do this Django email notification
https://docs.djangoproject.com/en/1.8/topics/email/#send-mail
I have a basic task form and option to assign it to someone, when the form is saved I want to send an email notification to the assigned user.
Job/task models.py
class Job(models.Model):
completed = models.BooleanField(default=False)
task_name = models.CharField(max_length=80, blank=False)
description = models.CharField(max_length=80, blank=False)
is_important = models.BooleanField(default=False)
completion_date = models.DateField(blank=True, null=True)
assign_to = models.ForeignKey(User, blank=True, null=True)
comments = models.TextField(blank=True)
def __unicode__(self):
return self.task_name
Job/task view.py
#login_required
def job(request):
if request.method == 'POST':
form = JobForm(request.POST)
if form.is_valid():
job_record = form.save(commit=False)
job_record = form.save(commit=False)
job_record.user = request.user
job_record.save()
return redirect('jobs:list')
else:
form = JobForm()
return render(request, 'jobs/form.html', {'form': form})
You are nearly there:
#login_required
def job(request):
form = JobForm(request.POST or None)
if form.is_valid():
job_record = form.save(commit=False)
job_record.assign_to = request.user
job_record.save()
send_mail(
subject="subject",
message="message",
from_email="from#myserver.com",
recipient_list=[job_record.assign_to.email]
)
return redirect('jobs:list')
return render(request, 'jobs/form.html', {'form': form})

Categories