How to create a URL for templateView? - python

How can I write a url for a form using TemplateView. I wrote a method to validate and pass the company details through form. Using that form object that I'm trying to access the HTML fields.
Form.py
class CompanyDetailsForm(forms.Form):
class meta:
fields = ['company_name','contact_person','employee_count','email','mobile_number']
widgets = {
'comment':Textarea(attrs={'cols':30,'rows':5}),
}
company_name = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'company Name'}))
contact_person = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Contact Person'}))
email = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Email'}))
employee_count = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Number Of Employee'}))
mobile_number = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder':'Mobile Number'}))
View.py
class GetCompanyView(TemplateView):
template_name = "astra/company_details.html"
form = CompanyDetailsForm()
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['form']=self.form
return context
def company_details(request):
if request.method =="POST":
form = CompanyDetailsForm(request.POST)
if form.is_valid():
company_name = form.cleaned_data['company_name']
contact_person = form.cleaned_data['contact_person']
email = form.cleaned_data['email']
employee_count = form.cleaned_data['employee_count']
mobile_number = form.cleaned_data['mobile_number']
try:
form.save()
send_mail(company_name,contact_person,email,employee_count,mobile_number,['salesastra500#gmail.com'])
except BadHeaderError:
return BadHeaderError
return render(request,'astra/company_details.html',{'form':form})
else:
return render(request,'astra/company_details.html')
I want to run my company_details.html file using TemplateView. I'm not able to write the url for same. Plz suggest

TemplateView only have get method
def get(self, request, *args, **kwargs):
return render(request,self.template_name, {'form': self.form})
if you have get and post methods use FormView

Related

Django python setting initial values dynamically to form

I'm building a small web service for inventory control. As part of this, I want to populate a detail view for any of the inventory items. This is what I have so far for that:
class Product_Update(forms.Form):
Product_Code = forms.CharField(
max_length=10,
attrs={"placeholder = <ID here> Readonly = True"
)
Name = forms.CharField(max_length=100)
Description = forms.Textarea(attrs={"Rows": 3})
price = forms.DecimalField()
mini = forms.IntegerField()
Max = forms.IntegerField()
How do I pass the form the parameters?
You should use a ModelForm instead:
class ProductUpdate(forms.Form):
class Meta:
model = Product
fields = ('product_code', 'name', 'description', 'price', 'mini', 'max')
Now you can easily pass a model instance to your form:
def some_view(request):
instance = Product.objects.first()
form = ProductUpdate(request.POST or None, instance=instance)
context = {'form':form}
return render(request, 'some_template.html', context)
If you want to show multiple products in the same form, you will need to use modelformset_factory:
from django import forms
ProductFormSet = forms.modelformset_factory(Product, form=ProductUpdate, extra=0)
Now in your views.py, you can pass a QuerySet to your form:
def some_view(request):
queryset = Product.objects.all()
form = ProductFormSet(request.POST or None, queryset=queryset)
if request.method == 'POST' and form.is_valid():
form.save()
context = {'form':form}
return render(request, 'some_template.html', context)
You can access the form's data in the view by accessing request.POST
def actionView(request, product_id):
product = Product.objects.get(id=product_id)
form = ProductUpdate(request.POST, instance=product_id)
form.save(commit=False) #Do this if you want to make changes to some value
form.price = 112233
updated_form = form.save()

Django NameError: request is not defined in class based view [duplicate]

How do I get the current logged in user in forms.py? I am trying to pre-populate the email field of the current user.
class ContactMe(forms.Form):
name = forms.CharField(label = "Name")
email_address = forms.CharField(label = "Email Address", intital = request.user.email)
subject = forms.CharField(label = "Subject")
message = forms.CharField(label = "Message", widget=forms.Textarea(attrs={'cols': 10, 'rows': 3}))
additional_comments = forms.CharField(required = False)
class Meta:
model = Contact_me
I tried passing request from views.py as :
contact_form = ContactMe(request.POST or None, request)
and then receiving the request inside of class ContactMe as :
class ContactMe(forms.Form, request):
name = forms.CharField(label = "Name")
email_address = forms.CharField(label = "Email Address", intital = **request.user.email**)
subject = forms.CharField(label = "Subject")
message = forms.CharField(label = "Message", widget=forms.Textarea(attrs={'cols': 10, 'rows': 3}))
additional_comments = forms.CharField(required = False)
class Meta:
model = Contact_me
It throws the error NameError: name 'request' is not defined. I know request is accessible in html, models.py, views.py. How to get it in forms.py?
The views.py :
def list_posts(request):
request.session.set_expiry(request.session.get_expiry_age()) # Renew session expire time
instance_list = Post.objects.all()
register_form = UserRegisterForm(data=request.POST or None)
if register_form.is_valid():
personal.views.register_form_validation(request, register_form)
login_form = UserLoginForm(request.POST or None)
if login_form.is_valid() :
personal.views.login_form_validation(request, login_form)
feedback_form = FeedbackForm(request.POST or None)
if feedback_form.is_valid() :
personal.views.feedback_form_validation(request, feedback_form)
contact_form = ContactMe(request.POST or None, request)
if contact_form.is_valid() :
personal.views.contact_form_validation(request, login_form)
if request.POST and not(register_form.is_valid() or login_form.is_valid()):
if request.POST.get("login"):
return accounts.views.login_view(request)
else:
return accounts.views.register_view(request)
template = 'blog/archives.html'
dictionary = {
"object_list" : content,
"register_form" : register_form,
"login_form" : login_form,
"feedback_form" : feedback_form,
"contact_form" : contact_form,
}
return render(request,template,dictionary)
You are trying to pass the request when constructing the form class. At this point there is no request. The request only exists inside your view function. You should, therefore, pass the request in your view function when constructing the form instance. To prepopulate the form, you can use the initial keyword of the form constructor. It takes a dictionary of field names and values as input.
Example:
#views.py
from django.shortcuts import render
from django import forms
class TestForm(forms.Form):
foo = forms.CharField()
def test_form(request):
form = TestForm(initial=dict(foo=request.<some_property>))
context = dict(form=form)
template_name = 'testapp/test.html'
return render(request, template_name, context)
This line is wrong class ContactMe(forms.Form, request).
(Hint: request isn't a base class for your form)
The correct way is to access the user in the __init__ method of the form:
class ContactMe(forms.ModelForm):
class Meta:
model = Contact_me
fields = '__all__'
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(ContactMe, self).__init__(*args, **kwargs)
The corresponding line in the views.py:
contact_form = ContactMe(request.POST, user=request.user)
Also you get this error if you write requests instead of request
Example
in views.py
def all_products(requests):
products = Product.objects.all()
return render(request, 'store/home.html', {'products': products})
should be:
def all_products(request):
products = Product.objects.all()
return render(request, 'store/home.html', {'products': products})
This was my issue, that's why I bring it up.

How to pass user object to forms in Django

How would I pass a user object or a request to my form for using it as an initial value for input textbox?
For example, I have my form:
class ContactForm(forms.Form):
contact_name = forms.CharField(required=True, initial="???")
contact_email = forms.EmailField(required=True)
subjects = forms.ChoiceField(choices=emailsubjects)
content = forms.CharField(
required=True,
widget=forms.Textarea
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = "Your name:"
self.fields['contact_email'].label = "Your email:"
self.fields['content'].label = "What do you want to say?"
self.fields['subjects'].label = "Please, select the subject of your message"
Where i want my user.first_name to be as a default value for contact_name field.
Here is my views.py, where i call for form:
def ContactsView(request):
form_class = ContactForm(request=request)
# new logic!
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
form_content = request.POST.get('content', '')
subjects = form.cleaned_data['subjects']
subjects = dict(form.fields['subjects'].choices)[subjects]
# Email the profile with the
# contact information
template = get_template('threeD/email/contact_template.txt')
context = Context({
'contact_name': contact_name,
'subjects': subjects,
'contact_email': contact_email,
'form_content': form_content,
})
content = template.render(context)
email = EmailMessage(
"New message from " + contact_name,
content,
"Message - " + subjects + ' ',
['smart.3d.printing.facility#gmail.com'],
headers={'Reply-To': contact_email}
)
email.send()
messages.success(request, "Thank you for your message.")
return redirect('/index/contacts/')
return render(request, 'threeD/contacts.html', {
'form': form_class,
})
Any help would be very much appreciated
You have changed your form to take the request object. Therefore you can access self.request.user inside your form's methods:
class ContactForm(forms.Form):
...
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['contact_name'].label = "Your name:"
self.fields['contact_name'].initial = self.request.user.first_name
You also have to update your view to pass the request object. Remember to update the code for GET and POST requests.
if request.method == 'POST':
form = ContactForm(data=request.POST, request=request)
...
else:
# GET request
form = ContactForm(request=request)
Finally, by passing the request to the form, you have tightly coupled it to the view. It might be better to pass the user to the form instead. This would make it easier to test the form separately from the view. If you change the form, remember to update the view as well.
You need to pass the initial values in the view:
views:
def ContactsView(request):
form_class = ContactForm(request=request,
initial={'contact_name': request.user.first_name})
...

Form submission not generating new Post object

I'm currently creating a Social platform with Django. Right now, I'm developing their Dashboard and want endusers to be able to publish their own posts. This is my Post model:
class Post(models.Model):
user = models.ForeignKey(User)
posted = models.DateTimeField(auto_now_add=True)
content = models.CharField(max_length=150)
Likes = models.IntegerField(default=0)
def __str__(self):
return self.user.username
My Form for the Post model:
class Post_form(forms.ModelForm):
class Meta:
model = Post
fields = (
'content',
]
def __init__(self, *args, **kwargs):
super(Post_form, self).__init__(*args, **kwargs)
self.fields['content'].label = ""
self.fields['content'].widget.attrs={
'id': 'id_content',
'class': 'myCustomClass',
'name': 'name_content',
'placeholder': 'What are you thinking about?',
}
When the form gets submitted, it correctly generates a POST request with the value of the content field. When I save my form in the view, no new post gets generated. What am I doing wrong?
My views.py:
def dashboard_view(request):
if request.POST:
form = Post_form(data=request.POST, instance=request.user)
if form.is_valid():
form.save() // <- no new post gets generated after saving
return redirect(reverse('dashboard'))
else:
return redirect(reverse('settings'))
else:
form = Post_form
gebruikers = User.objects.all()
all_posts = Post.objects.all().order_by('-posted')
return render(request, 'Dashboard/index.html', {'gebruiker':gebruikers, 'posts':all_posts, 'form': form},)
You can't pass the user as the instance parameter to a Post form. You should omit that argument and assign the user on the actual Post instance returned from save.
form = Post_form(data=request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()

Django: __init__() got an unexpected keyword argument 'instance'

I have the following form:
class locationForm(forms.Form):
existing_regions= forms.ModelChoiceField(queryset=Region.objects.none(), label="Region Name", required=False)
region_name = forms.CharField()
location_name = forms.CharField()
street_address = forms.CharField()
city = forms.CharField()
zip_code = forms.CharField()
And the following update view for this form:
class UpdateLocation(View):
template_name = "dash/location_update_form.html"
def get(self, request, *args, **kwargs):
loc = kwargs['name']
try:
location = Location.objects.get(name=loc)
form = locationForm(instance=location)
return render(request, self.template_name, {'form': form,'location': location})
except (ValueError, ObjectDoesNotExist):
return redirect(reverse('geofence_manager'))
def post(self, request, *args, **kwargs):
loc = self.kwargs['name']
try:
location = Location.objects.get(name=loc)
form = locationForm (request.POST, instance=location)
if form.is_valid():
form.save()
else:
form = locationForm(request.POST, instance=location)
return render(request, self.template_name, {'location': location, 'form': form})
except (ValueError, ObjextDoesNotExist):
return redirect(reverse('location_manager'))
return redirect(reverse('location_manager'))
I am receiving an error in regards to 'instance' key word argument being used. I believe this has something to do with me not using a Modelform(I could be wrong). But I do not want to use a Modelform to construct my form, so is there a way I can get around this?
class locationForm(ModelForm):
class Meta:
model = Location
fields = '__all__'
in your view:
...
locationForm.base_fields['existing_regions'] = forms.ModelChoiceField(queryset= ...)
form = locationForm()

Categories

Resources