Submit a form only once in Django - python

I am trying to make the user submit a form only once. I have a /dashboard page which is shown after submitting the /petform. But, I want the user to submit the form only once after logging in and other times it should redirect to the /dashboard directly (or show a message that "form already submitted").
models.py
class PetFormData(models.Model):
abstract = True
name = models.CharField(max_length=100)
age = models.IntegerField()
breed = models.CharField(max_length=100)
amount_spent = models.CharField(max_length=100, choices=AMOUNT_CHOICES)
pincode = models.CharField(max_length=15)
services_required = models.CharField(max_length=100, choices=SERVICE_CHOICES)
auth_user_email = models.ForeignKey(User, on_delete=models.CASCADE)
form_submitted = models.BooleanField(default=False)
views.py
#login_required
def showformdata(request):
form = PetForm(request.POST)
if request.method == 'POST':
if not PetFormData.form_submitted and user == PetFormData.auth_user_email:
PetFormData.form_submitted = True
print(PetFormData.form_submitted)
if form.is_valid():
user = request.user
nm = form.cleaned_data['name']
age = form.cleaned_data['age']
breed = form.cleaned_data['breed']
am_sp = form.cleaned_data['amount_spent']
pin = form.cleaned_data['pincode']
ser_req = ','.join(form.cleaned_data['services_required'])
model_pet_form = PetFormData(name=nm, age=age, breed=breed, amount_spent=am_sp, pincode=pin,
services_required=ser_req, auth_user_email=user)
model_pet_form.save()
print(session_data)
return redirect('/dashboard')
else:
print(PetFormData.form_submitted)
return HttpResponse('Form already submitted', content_type="text/plain")
else:
form = PetForm()
return render(request, 'petform.html', {'form': form})

Successfully submitting the form once presumably stores something in the database. A subsequent visit to that page can interrogate the database, discover it has already been done, and display the appropriate next page.
Something like this (I don't fully understand your problem)
if PetFormData.objects.filter( auth_user_email = request.user).exists() :
return redirect('/dashboard')
# OK, user hasn't submitted yet.

Related

I need to get the value of the field that we enter in the form and immediately take action on it

I need to get the value of the field that we enter in the form (in this case, these are the days of reservation) and immediately calculate the cost of the reservation based on it
And the problem is that I don’t understand how to get the value of these very fields (so this is not QuerySet request, and not accessing the database)
This is my views:
def booking(request):
error = ''
if request.method == 'POST':
form = BookingForm(request.POST)
if form.is_valid():
booking = form.save(commit=False)
booking.user = request.user
booking.sum = #create sum function
form.save()
return redirect('account')
else:
error = 'Форма не корректна'
form = BookingForm()
context = {
'form': form,
'error': error
}
return render(request, 'bookings/booking.html', context)
And this is models:
class Booking(models.Model):
startdate = models.DateField('Startgdate')
finishdate = models.DateField('Finishdate')
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
sum = models.PositiveIntegerField('Sum')
fullname = models.CharField('Full name', max_length=50)
pnumber = models.PositiveBigIntegerField('Phone number')
def __str__(self):
return self.fullname
class Meta:
verbose_name = 'Booking'
verbose_name_plural = 'Bookings'
thanks in advance
This is needs Ajax (which can be done by JQuery or Fetch API) that runs on input onchange and a simple view that receives that value and return a the value of cost reservation.

How Can I set and Get Django Form Value on Another View

I am working on a Django Ticketing project where I want guest to activate Ticket PIN and then register for the event they bought the ticket for. And I also want them to have login user access and be able to update profile immediately after login.
The application usually start with PIN activation and thereafter guest registration. The issue is that I don't know how to pass the PIN value from the PIN activation view to the guest registration view.
Notice that I have used request.session['pin'] = pin_value to set the PIN as the session variable in the pin activation view and got it using user_pin = request.session.get('pin') in the register guest view but only the Guest.objects.create(guest_name=new_user, pin=user_pin) in the register guest view gets the session variable while the Pin.objects.filter(value=user_pin).update(status='Activated') fails to get the session variable for the registration process to be completed. I have tried using a literal value in the Pin filter and update query and it worked but using the session variable does not.
Below are my models:
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
pin = models.CharField(max_length=6, default='No Pin', blank=True)
def __str__(self):
return f"{self.guest_name}"
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=20, null=True)
othernames = models.CharField(max_length=40, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
phone = PhoneNumberField()
image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images',
)
def __str__(self):
return f'{self.user.username}-Profile'
class Pin(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
added = models.DateTimeField(auto_now_add=True, blank=False)
reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
status = models.CharField(max_length=30, default='Not Activated')
#Save Reference Number
def save(self, *args, **kwargs):
self.reference == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.ticket
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket}"
def get_absolute_url(self):
return reverse("pin-detail", args=[str(self.id)])
My Views code:
def pin_activation(request):
if request.method == "POST":
#Create PIN form
form = PinActivationForm(request.POST)
#Get User Pin Value from Form
pin_value = form['pin'].value()
#Check if the the form has valid data in it
if form.is_valid():
try:
#Get user Pin with the one in the Database
check_pin_status = Pin.objects.get(value=pin_value)
except Pin.DoesNotExist:
messages.error(request, f'{pin_value} Does Not Exist')
return redirect('pin-activation')
else:
#Check PIN status
if check_pin_status:
#Get Event Ticket Date of the PIN
event_date = check_pin_status.ticket.event.date
#Get Current Date
current_date = datetime.now().date()
#Check if Event Date is Passed the Current Date
if event_date < current_date:
messages.error(request, 'Event Has Passed')
return redirect('pin-activation')
else:
#Update the User Pin with a new status of Activated
Pin.objects.filter(value=form['pin'].value()).update(status='Validated')
#Message the User
messages.success(request, 'Pin Validated Successfully')
#Redirect the user to register for seat
return redirect('register-guest')
#Check filter the DB where the PIN status is Validated
request.session['pin'] = pin_value
elif Pin.objects.filter(value=form['pin'].value(), status="Validated"):
messages.error(request, 'Pin Already Validated. Register for Seat')
return redirect('register-guest')
#Check Filter PIN in DB where Status is Activated
elif Pin.objects.filter(value=form['pin'].value(), status="Activated"):
messages.error(request, "Pin Already Activated, Login.")
return redirect('user-login')
else:
messages.error(request, 'Something Went Wrong. Try again')
else:
form = PinActivationForm()
context = {
'form':form,
}
return render(request, 'user/pin_activation.html', context)
def register_guest(request):
#get session variable
user_pin = request.session.get('pin')
form = GuestUserForm(request.POST)
page_title = "Festival Registration"
if request.method == 'POST':
form = GuestUserForm(request.POST)
pin_form = PinActivationForm(request.POST)
if form.is_valid() and pin_form.is_valid():
new_user = form.save()
Guest.objects.create(guest_name=new_user, pin=user_pin)
Pin.objects.filter(value=user_pin).update(status='Activated')
messages.success(request, 'Registered Successfully. Login')
return redirect('user-login')
else:
form = GuestUserForm()
pin_form = PinActivationForm()
context = {
'form':form,
'pin_form':pin_form,
'page_title':page_title,
}
return render(request, 'user/register.html', context)
Someone should please help with the best way of solving this problem. Thanks
you cannot save a quest as a User in this way.
Do something like this.
From youre form get the username.
Then create a new User with that username and create the Guest with that new user.
//simple form --> get it in youre template
class GuestUserForm(forms.Form):
username = forms.CharField()
password=forms.CharField()
//create new user from the form in template
user_guest = form.cleaned_data.get("username")
new_user = User.objects.create_user(username=user_guest)
//create new guest with created user
Guest.objects.create(guest_name=new_user)
//youre view function
def register_guest(request):
if request.method == 'POST':
form = GuestUserForm(request.POST)
if form.is_valid():
user_guest = form.cleaned_data.get("username")
print(user_guest)
new_user = User.objects.create_user(username=user_guest)
Guest.objects.create(guest_name=new_user)
form = GuestUserForm()
return render(request, "index.html",{"form":form})

associate the user with the post Django and MySQL

I am trying to associate the user with the post. I have two models students is for user and sublists is for user posts with a foreign key(author). I am using MySQL database and using forms to store data into them. when my form.author execute in my HTML file it gives me a list of ids for all users in the databse but I am already logged in and i want to post as the logged in user without choosing. If remove it says my form is not valid which make sense since im not inputing for form.author.Since I'm using MySQL, I'm not using the built-in User authentication method, but instead comparing both email and password with the login form input. Spend too much time on this but hard to get around with this one. Any help would be appreciated
my views.py look like this
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, ' Subscirption Saved')
name = sublist.objects.get(name=name)
return render (request, 'subscrap/main.html', {'sublist': name})
except:
pass
else:
messages.success(request, 'Error')
pass
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
#login_required(login_url='login')
#cache_control(no_cache=True, must_revalidate=True, no_store=True)
def main(request):
return render(request, 'subscrap/main.html')
def mod(request):
student = students.objects.all()
return render(request, 'subscrap/mod.html' , {'students': student})
My Models.py
class students(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
password = models.CharField(max_length = 50 , null = True)
passwordrepeat = models.CharField(max_length = 50, null = True)
email = models.EmailField(max_length=150)
class Meta:
db_table = "students"
class sublist(models.Model):
author = models.ForeignKey(students, related_name='sublist' ,on_delete=models.CASCADE)
name = models.CharField(max_length=150)
cost = models.IntegerField(default = 0)
renewalcycle = models.IntegerField(default = 0)
class Meta:
db_table = "sublist"
Since I'm using forms here's my forms.py
lass StudentForm(forms.ModelForm):
class Meta:
model = students
fields = "__all__"
class Studentlogin(forms.Form):
email = forms.EmailField(max_length=150)
password = forms.CharField(max_length = 50, widget=forms.PasswordInput)
class Sublist(forms.ModelForm):
class Meta:
model = sublist
fields = "__all__"
Exclude the Author from the Sublist form:
class Sublist(forms.ModelForm):
class Meta:
model = sublist
exclude = ['author']
In the addnew method, you associate the .instance.author with the request.user:
#login_required(login_url='login')
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
form.instance.author = request.user
form.save()
messages.success(request, ' Subscirption Saved')
return redirect('some_view')
else:
messages.error(request, 'Error')
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from sublist to Sublist.
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use SublistForm instead of
Sublist.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the students directly. For more information you can see the referencing the User model section of the documentation.

Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance

I'm working on a project "Beauty Parlour Management System" and I got this error (Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance.) anyone here can help me, please.
When I am filling a book appointment form then I got this error.
models.py
class Service(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField(default=0)
image = models.ImageField(upload_to='uploads/productImg')
class Appointment(models.Model):
your_name = models.CharField(max_length=100)
your_phone = models.CharField(max_length=10)
your_email = models.EmailField(max_length=200)
your_service = models.ForeignKey('Service', on_delete=models.CASCADE, default=1)
your_date = models.DateField()
views.py
def appointments(request):
if request.method == 'GET':
return render(request, 'core/bookappointment.html')
else:
your_name = request.POST.get('your-name')
your_phone = request.POST.get('your-phone')
your_email = request.POST.get('your-email')
your_service = request.POST.get('your-service')
your_date = request.POST.get('your-date')
details = Appointment(
your_name = your_name,
your_phone = your_phone,
your_email = your_email,
your_service = your_service,
your_date = your_date)
details.save()
return render(request, 'core/appointments.html')
You create this by assigining the method to your_service_id field, if you work with your_service, it should be a Service object:
details = Appointment.objects.create(
your_name=your_name,
your_phone=your_phone,
your_email=your_email,
your_service_id=your_service,
your_date=your_date
)
That being said, it is usually better to validate, clean, and save the data with a ModelForm, not manually.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
def appointments(request,pk):
record = get_object_or_404(Service,pk=pk)
if request.method == 'POST':
form = appointmentsForm(request.POST,request.FILES)
if form.is_valid():
appointment= form.save(commit=False)
appointment.your_service = record
appointment.save()
return render(request, 'core/bookappointment.html')
else:
return render(request, 'core/appointments.html')

Passing logged in user to form

I am trying to pass logged in user to form that i would like to save.
forms.py
class SpotForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SpotForm, self).__init__(*args, **kwargs)
self.fields['gross_weight'].widget = forms.NumberInput(attrs={'min':0})
self.fields['volume'].widget = forms.NumberInput(attrs={'min': 0})
class Meta:
model = Spot
fields = [
'gross_weight','volume','origin_country','origin_port',
'dest_country','dest_port','ship_week','requestor'
]
models.py
class Stakeholder(models.Model):
user = models.OneToOneField(User,null=True,blank=True,on_delete=models.CASCADE)
company_name = models.CharField(max_length=15)
mail = models.CharField(max_length=40)
def __str__(self):
return self.mail
class Spot(models.Model):
STATUSES = (
('Open','Open'),
('Closed','Closed')
)
gross_weight = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
volume = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
origin_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
origin_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
dest_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
dest_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
time_registered = models.DateField(default=timezone.now)
spot_status = models.CharField(max_length=6,default='Open', choices=STATUSES)
ship_week = models.CharField(max_length=2,null=True)
requestor = models.ForeignKey(Stakeholder,null = True,on_delete=models.CASCADE)
def __str__(self):
return self.origin_country + self.origin_port + '-' + self.dest_country +self.dest_port + '-' + self.ship_week
views.py
def register_spot(request):
my_user = Stakeholder.objects.get(user=request.user)
form = SpotForm()
if request.method =='POST':
print("print",request.POST)
form = SpotForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
print(form.errors)
context = {'form': form}
return render(request, 'spotrequesting/register_spot.html', context)
When i submit the form i am getting an error in command prompt stating "This field is required" for "requestor". After that - dropdown list for this field come up on screen and i can select out of two registered users i have. But even selecting something from this list and again submitting the form is giving me the same error.
Checking "my_user" variable - it is showing me that i am logged in.
Is there a way to pass to "requestor" field currently logged in user?
I was able to get the form saved only by deleting "requestor" from "fields" in SpotForm (which gave me "None" in the end for this field in database) but that's not the desired outcome.
Any suggestion would be highly appreciated.
You are not really passing the stakeholder instance to the requestor field in the form are you? So you will have to do:
form = SpotForm(requestor = my_user)

Categories