Save a form using django's authentication framework? - django

I'd like to be able to save data submitted by the form based on the user that is signed in (instead of having the user to write his/her name through a textbox). I am using django's built-in authentication system. Any thoughts on how I can accomplish this?
#login_required
def add_review(request, product_id):
p = get_object_or_404(Productbackup, pk=product_id)
if request.method == 'POST':
form = ReviewbackupForm(request.POST)
if form.is_valid():
review = form.save(commit=False)
review.product = p
#how to save user as well? review.user = user
review.save()
return HttpResponseRedirect(reverse('reserve.views.view_reviews', kwargs={'product_id':p.id}))
else:
form = ReviewbackupForm()
variables = RequestContext(request, {'form': form, 'product_id': product_id})
return render_to_response('reserve/templates/create_review.html', variables)

You've using save with commit=False so you're almost there. You can get the logged in user from the request object.
if form.is_valid():
review = form.save(commit=False)
review.product = p
review.user = request. user
review.save()
For more details, see the Django docs for user authentication.

Related

how to check whether user after login has submitted the form one , if yes again if he login he should redirect to form 2 not one again in django

I have an app where user login and after he logins he get redirect to dashboard where appears a form and user fill the form , once user fill the form he redirect to next page where it shows the progress of the form. So if user login again he should automatically redirect to the progress page he should not get the form page again if he has filled it .
Can any one suggest me how to achieve these.
views.py
def create(request):
if request.method == 'POST':
post = AccountProfile()
post.user = request.user
post.name = request.POST['name']
post.email = request.POST['email']
post.mobile = request.POST['mobile']
post.date = request.POST['date']
post.sex = request.POST['sex']
post.save()
return render (request,'posts/dashboard-post-a-job.html')
These is the views where user get redirect after login and fill form.
You should store the progress in the database. If you need to check for only one form, then add a new column in AccountProfile model.
models.py
class AccountProfile(models.Model):
...
form1_submitted = models.BooleanField()
Then, once the form is submitted, you can update this field.
def create(request):
if request.method == 'POST':
post = AccountProfile()
post.user = request.user
post.name = request.POST['name']
post.email = request.POST['email']
post.mobile = request.POST['mobile']
post.date = request.POST['date']
post.sex = request.POST['sex']
post.form1_submitted = True # save the progress
post.save()
return render (request,'posts/dashboard-post-a-job.html')
Now, the progress page can check the value of this field and render the form accordingly.

how to do i automatically set the user field to current user in django modelform

How can i set the current login user to the user field of django model .In my view ,i am using function base view .My model is something like this .
Model.py
class DistributionProfile(Abstract_Class):
Distributortype =(
('B2B1','b2b'),
('b2c','b2c'),
('c2c','c2c'),
('govt4','govt'),
)
ManufacturerType=(('Machine1','Machines'),
('Pharmaceutical2','Pharmaceutical'),
('Jewelries3','Jewelries'),
('Furniture4','Funitures'),
('Electronics5','Electronics'),('Textile6','Textile'),
('Constructionmaterials7','ConstructionHardware'),
('Beverages8','Beverages'),
('Cosmetics9','Cosmetics'),
('Convectionaries10','Convectionaries'),
('AgriculturalProduce11','AgriculturalProduce'),
('RawMaterials12','RawMaterials'),
('CrudOil13','CrudOil'),
('SeaFood14','SeaFood'),
)
title =models.CharField(choices=Distributortype ,null=True,max_length=250,blank=False)
ManufacturerOfInterest =MultiSelectField(choices=ManufacturerType,null=True,blank=False,max_choices=14)
verified = models.BooleanField(default=False,blank=True)
promot=models.BooleanField(default=False,blank=False)
slug = models.SlugField(default='')
user=models.ForeignKey(User,null=True,on_delete=models.CASCADE)
bellow is my form.I would love the form to automatically have the information of the login user filling the form .Meaning the user field should automatically have the information of the login in user .So that i can easily query and display objects created by the login user
form.py
class DistributionProfileForm(forms.ModelForm):
class Meta:
model= DistributionProfile
exclude= ['slug','user','CreatedTime','verified','promot','UpdatedTime']
widgets ={
'CompanyRegisteredName':forms.TextInput(attrs={'class':'distributorform','placeholder':'Name of your company','autofocus':'True'}),
'CompanyRegisteredState':forms.TextInput(attrs={'class':'distributorform','placeholder':' StateOfRegistry'}),
'CompanyRegisteredAddress':forms.TextInput(attrs={'class':'distributorform','placeholder':'Company Address'}),
'CompanyRegisteredCity':forms.TextInput(attrs={'class':'distributorform','placeholder':'Company registered city'}),
'CompanyWebsiteLink':forms.TextInput(attrs={'class':'distributorform','placeholder':'www.mycompany.com'}),
'RegisteredCompanyType':forms.Select(attrs={'class':'distributorform '}),
'Country':forms.Select(attrs={'class':'distributorform'}),
'ManufacturerOfInterest ':forms.CheckboxSelectMultiple(attrs={'class':'multiple_select'}),
}
fields=['CompanyRegisteredName',
'CompanyRegisteredState',
'CompanyRegisteredAddress',
'CompanyRegisteredCity',
'CompanyWebsiteLink',
'RegisteredCompanyType',
'Country','title',
'ManufacturerOfInterest'
]
view.py
def SetUpDistributor(request):
if not request.user:
return HttpResponse('login to access this page ')
if request.method =='POST':
distributor = DistributionProfileForm(request.POST,request.FILES)
if distributor.is_valid():
distributor.save(commit=False)
distributor.user=request.user
distributor.save()
messages.success(request,'Distributor profile created ')
return redirect('gbiz1990:distributor_profile_setup')
else:
messages.error(request,'Something went wrong')
else:
distributor=DistributionProfileForm()
return render(request,"gbiz1990/User_function_pages/distributors.html",{'distributor':distributor})
Your views, may looks like that:
def your_view(request):
form = YourForm(request.POST or None)
if form.is_valid():
your_object = form.save(commit=False)
your_object.user = request.user
your_object.save()
return redirect('your_success_url')
context = {'form': form}
return render(request, 'your_template.html', context)
You need to adapt some parts, but in the general the should be your view. You need to pay attention to that this view needs a login_required decorator in order to not allow non-logged users to create objects.
Use the request.user. I don't know how your app works but when creating, do this:
model = ModelName(user = request.user)
model.save()
I used ModelName because it is best practise to start a class name with a capital, which is not fulfilled in your create model. I suggest you change this.
There also seems to be a mistake in your view, it should be request not reques.
Your view could be like so:
def index(request):
form = FormName(request.POST or None)
if form.is_valid():
form.save()
return render(request, "path/to/template", {"form": form})
And your template could be:
<form method="POST" action="">
{{ form }}
<input type="submit">
</form>
So i solved my problem
in my model.py
class SetdistributorProfile(models.Model):
user=modelss.foreignkey(settings.AUTH_USER_MODEL,null=True,unique=True)
views.py
def SetDistribution(request):
if not requested.user.is_authenticated:
return redirect('app_name:url_name)
if request.method === 'POST':
dis = MymodelForm(request.POST or None)
if dis.is_valid():
instance=dis.save(commit=False)
instance.user=request.user
instance.save()
return redirect('myappname:urlname')
else:
instance=MymodelFomr()
context={'intance':intance}
return render(request,'page.hmtl',context)
Another way to solve this in your views.py
if request.method == "POST":
yourModel = YourModel(user_id = request.user.id)
form = YourModelForm(request.POST, request.FILES, instance=yourModel)
if form.is_valid():
form.save()

Deleting records in Django via forms

I would like to be able to present a form to users with a dropdown list of existing records and a delete action for the selected record. So far all I can find are examples that pass the id of record to the form (such as below) and I can get this to work if I hard code the id in the function, but that's obviously not a solution. What am I missing? Thanks.
def DeleteRecord(request, id):
to_delete = get_object_or_404(MyModel, id=id)
#+some code to check if this object belongs to the logged in user
if request.method == 'POST':
form = DeleteRecordForm(request.POST, instance=to_delete)
if form.is_valid(): # checks CSRF
to_delete.delete()
return HttpResponseRedirect("/")
else:
form = DeleteRecordForm(instance=to_delete)
data = {'form': form}
return render(request, 'deleteprimerpair.html', data)

How can I overwrite the old record instead of creating a new one?

I am following <"http://tutorial.djangogirls.org/en/django_forms/index.html"> Django Girls to create my first web application project.
I have created form and added the username password option.
Now , I login as "user1" and input some data in form.
Again, I login as "user1" and input some data in form.
What's happening is instead of overwriting(which I thought would happen) it's creating new database.
I want form to update when user login again
One Example would be very helpful thanks in advance
you can just scroll down the blog you are referring to....they have explained the edit form in detail link
In brief: You have to add a new url to edit your user like:
url(r'^user/(?P<pk>[0-9]+)$', views.UserEdit),
and in views:
def UserEdit(request, pk):
user = get_object_or_404(User, pk=pk)
if request.method == "POST":
form = UserForm(request.POST, instance=user)
if form.is_valid():
...
return redirect('detail_user', pk=user.pk)
else:
form = UserForm(instance=user)
return render(request, 'user_detail.html', {'form': form})

django session key error for my simple captcha form

I just write a simple captcha for my login form.
I just add a simple session data.request.session['captcha'].
This is the login views function:
login (request):
if request.method =='GET':
form = LoginForm(auto_id=True)
a = random.randrange(1,10,1)
b = random.randrange(10,20.1)
request.session['captcha1']=a
request.session['captcha2']=b
return render_to_response('login.html',locals(),context_instance=RequestContext(request))
if request.method =='POST':
form = LoginForm(data=request.POST)
if form.is_valid():
captcha= request.POST.get('captcha','')
result = request.session.get('captcha1') + request.session.get('captcha2')
if captcha==result:
data = form.clean()
user=authenticate(username= data['username'],password = data['password'])
if user is not None:
auth_login(request,user)
return HttpResponseRedirect('/')
else:
form = LoginForm(auto_id=True)
return render_to_response('login.html',locals(),context_instance=RequestContext(request))
This is the login form
class LoginForm (forms.Form):
username = forms.CharField(
label='username')
password =forms.CharField(
label='password',widget = forms.PasswordInput())
captcha = forms.CharField(label='spam chercker')
I get keyerror for captcha1, captcha2, and when I add print request.session['captcha1'], it shows None. That means, when POST, I do not get the django session data, there is no data captcha1 and captcha2
How can I store the data in django session, and pass it to the POST method, and in other views function?
thanks
Instead of taking this approach, you might also want to look at existing Django captcha packages:
https://www.djangopackages.com/grids/g/captcha/
If you're looking for something simple, Django-Simple-Captcha is a great option.