Updating user profile - Django - python

I've created a template for updating account profiles using a Bootstrap snippet (from https://www.bootdey.com). With the django default format (like {{ form.as_p }}), updating accounts works (for example, when I modify the first name, it changes in the database). When I use the bootstrapp snippet, it doesn't update: it goes straight to 'homepage' without updating (as explained in views.py).
In forms.py
class EditAccountForm(UserChangeForm):
class Meta:
model = Account
fields = ('email','first_name','last_name')
In views.py
def EditProfile(request):
context= {}
if request.POST:
form = EditAccountForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
email = form.cleaned_data.get("email")
raw_password = form.cleaned_data.get("password1")
account = authenticate(email=email,password=raw_password)
return redirect('profile_page')
else:
context['edit_form'] = form
return redirect('homepage')
else:
form = EditAccountForm(instance=request.user)
context['edit_form'] = form
return render(request,'Account/edit_page.html',context)
the template: edit_profile.html (I only show the first_name part as example)
<form method = "POST" class="form" novalidate="">
{% csrf_token %}
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="form-group">
<label>First name</label>
<input class="form-control" type="text" name="firstna" value={{ edit_form.first_name.value }}>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col d-flex justify-content-end">
<button class="btn btn-primary" type="submit">Save Changes</button>
PS: I've preferred to use those snippets instead of the Django style since I find them more attractive and offer more freedom.

Please check you are taking same value if you are changing the data in views like if you are using (name="firstna") in template so for First Name you have to take same in views.
Same question is asked here you can go and follow below link
[How to update user profile in Django

Related

Disabling a crispy form field from showing errors

I have a form to perform searching. As I am using the primary key to search, The searching process is completed successfully BUT I used to get an error below the text field saying Invoice number already exists. I did some tweaks and stopped the form from showing errors but the text field still has a red outline whenever I perform the searching operation. How can I stop the form from doing that?
The code in the forms.py that disabled the form to show field errors:
class InvoiceSearchForm(forms.ModelForm):
generate_invoice = forms.BooleanField(required=False)
class Meta:
model = Invoice
fields = ['invoice_number', 'name','generate_invoice']
def __init__(self, *args, **kwargs):
super(InvoiceSearchForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_show_errors = False
self.helper.error_text_inline = False
self.form_error_title=False
The HTML code that deals with the search operation:
<div class="myForm">
<form method='POST' action=''>{% csrf_token %}
<div class="row">
<div class='col-sm-12'>
<div class="form-row">
<div class="form-group col-md-3">
{{ form.invoice_number|as_crispy_field }}
</div>
<div class="form-group col-md-3">
{{ form.name|as_crispy_field }}
</div>
<div class="form-group col-md-3">
{{ form.generate_invoice|as_crispy_field }}
</div>
<div class="form-group col-md-3">
<br>
<button type="submit" class="btn btn-primary">Search</button>
</div>
</div>
</div>
</div>
</form>
</div>
The views.py related to the search operation:
#login_required
def list_invoice(request):
title = 'List of Invoices'
queryset = Invoice.objects.all()
form = InvoiceSearchForm(request.POST or None)
context = {
"title": title,
"queryset": queryset,
"form":form,
}
if request.method == 'POST':
queryset = Invoice.objects.filter(invoice_number__icontains=form['invoice_number'].value(),name__icontains=form['name'].value())
context = {
"form": form,
"title": title,
"queryset": queryset,
}
return render(request, "list_invoice.html", context)
The red outline of the textbox that I get after performing search operation->
I think you need to use forms.Form instead of forms.ModelForm which is designed for creating and updating Model instances.

Recover data from a Django Form

It's my first time doing a Django Form challenge.
The challenge for now is just from a HTML Template get the last_name information and store into DB from views. So I have a scenario below:
models.py:
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
an HTML template, I will put below only the form part:
<form action="{% url 'store' %}" method="post">
{% csrf_token %}
<div class="form-group row">
<label for="last_name" class="col-sm-2 col-form-label">Last Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="last_name" placeholder="Last Name">
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Send Last Name</button>
</div>
</div>
</form>
And the views.py itself... I created a InsertLastName ModelForm to store the data from the form, but didn't work. For some reason, when I tryed to call form.cleaned_data I reveived an error about the is_valid() verification. Seens like that I'm not getting the information from label.
class InsertLastName(forms.ModelForm):
class Meta:
model = Person
fields = ['last_name']
exclude = ['first_name']
def index(request):
persons = Person.objects.all()
context = {'persons': persons}
return render(request, '/index.html', context)
def store(request):
form = InsertLastName(request.POST or None)
print(form.cleaned_data['last_name'])
return HttpResponse("Storing a new Last Name object into storage")
What is the correct way to get the information from last_name label in my form?
I'm following that documentation and coding from a challenge template.
Your just set attr name for your input html tag
Example:
<input type="text" name="first">
And for get input in function store in view.py:
request.POST.get("first")
Add this to your html template in your form
{{persons}}

Get the details of selected item

I have a part table and delivery instruction table (dins). To create a dins, I have to choose a part name. So what I want to do is, after choosing the part name from the dropdown that part's price will be visible in the form.
In the Part table, I have the price value for the specific part name. So during the creation of dins, after choosing such an example part name is X, then the form should show what is the price of that chosen part (X part) price.
Any idea how to make that happen?
views.py
def create_deliveryins(request):
from django import forms
form = DeliveryInsForm()
if request.method == 'POST':
forms = DeliveryInsForm(request.POST)
if forms.is_valid():
product = forms.cleaned_data['product']
usage = forms.cleaned_data['usage']
part= forms.cleaned_data['part']
deliveryins = DeliveryIns.objects.create(
usage=usage,
product=product,
part=part,
)
return redirect('dins-list')
context = {
'form': form
}
return render(request, 'store/addDins.html', context)
HTML
<form action="#" method="post" novalidate="novalidate">
{% csrf_token %}
<div class="form-group">
<label for="product" class="control-label mb-1">Product</label>
{{ form.product }}
</div>
<div class="form-group">
<label for="part" class="control-label mb-1">Part</label>
{{ form.part}}
</div>
<div class="form-group">
<label for="usage" class="control-label mb-1">Usage</label>
{{ form.usage }}
</div>
</form>
Create a hidden form field that has the part prices for each part.
Use Javascript or Jquery to update the form field for price and show it whenever the form part field is changed.
This would prevent the need for ajax, or additional views or requests.
You would only need to slightly modify your view and template.

Populate textarea field using WTForms

As I understand it, if you want to populate a textarea you place the text between the textarea tags. However I am using WTForms. How can I pre-populate the form from views or in my template?
FORM
class ModuleSectionForm(FlaskForm):
title = StringField('Section Title', validators=[DataRequired()])
description = TextAreaField('Description', validators=[DataRequired()])
submit = SubmitField('Add Section')
VIEW
#modules.route('/update_section/<name>/<title>', methods=['GET', 'POST'])
def update_section(name, title):
form = ModuleSectionForm()
module = Module.objects(title=name).first()
section = None
for sect in module.sections:
if sect.title == title:
section = sect
#if form.validate_on_submit():
#save data
return render_template('modules/update_section.html', section=section, form=form)
TEMPLATE
<form method="post" action="{{ url_for('modules.update_section', name=name) }}">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.title.label(class="form-control-label") }}
{{ form.title(class="form-control", value=section.title) }}
</div>
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{{ form.description(class="form-control", default=section.description) }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-secondary shadow") }}
</div>
</form>
This can be done by just assigning the text to display beforehand (in the view, for instance).
Try edit your view (update_section) this way:
+ form.description.data = 'text you want to display'
And your template as follows:
- {{ form.description(class="form-control", default=section.description) }}
+ {{ form.description(class="form-control") }}
Mind you, there's an alternative way, which is to specify the placeholder attribute (but I guess is not what you want to do here).
Typically with WTForms (let's assume you're using Flask and Bootstrap here), you'll use the value attribute of the input to pre-populate a form field. Note that pre-populating a field is distinct from providing a 'placeholder', which is just an ephemeral hint. So usually we pre-populate like this:
<div class="form-group row">
<label for="form_subject" class="col-sm-2 col-form-label">Subject</label>
<div class="col-sm-7">
<input class="form-control" id="form_framework" name="form_framework"
value="{{ instruct.Subject }}">
</div>
</div>
With Flask and Bootstrap, the name attribute is required to pass the value back to the Controller upon submission, the value attribute is used to pre-populate the field from the object - in this case, our controller has passed in an object called instruct, which has an attribute Subject.
But you have to be aware that different kinds of inputs in WTForms have different attributes, and this is left as a fun challenge for the developer to figure out.
TextArea doesn't have a value attribute, so in order to pre-populate the field, you have to provide the value between the tags, like so (again, using Bootstrap here in case any of these tags are unfamiliar):
<div class="form-group row">
<label for="form_longish_text"
class="col-sm-2 col-form-label">Longish Text</label>
<div class="col-sm-7">
<textarea class="form-control" rows="3"
id="form_longish_text"
name="form_longish_text">{{ instruct.LongishText }}
</textarea>
</div>
</div>

How to get logged in user id in Django

I am very new in Python and Django. A am trying to make app but I have an issue.
Can anyone help me, please xD
I can't get id of authenticated user...
I tried it in this way, and many other ways...
views.py
class CreateProfile(CreateView):
template_name = 'layout/add_photo.html'
model = Profile
fields = ['image', 'user']
html
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="username"> #Here has to be field filled in with logged in user
<input type="file" name="image">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Save Changes</button>
</div>
</div>
</form>
And when I'm starting app, and want to change/add picture, I can do it for anyone from my database, not only for logged in user.
enter image description here
Thanks for patience and help!
In the Django ClassBasedViews you can get your user's id as self.request.user.id and in your template as {{ user.id }}
To check if someone is authenticated you can use self.request.user.is_authenticated() and in your template {% if user.is_authenticated %} .. {% endif %}
class CreateProfile(CreateView):
template_name = 'layout/add_photo.html'
model = Profile
fields = ['image', 'user']
# For example, if you want to return to a certain user
# profile (which requires url adjustments to take a Primary Key)
def get_success_url(self):
user_id = self.request.user.id # Get user_id from request
return reverse_lazy('git_project:user_profile', kwargs={'id': user_id})

Categories

Resources