How to update image input with django forms and template - javascript

I have a django project where a user has a profile and can upload a profile picture. The models.py is:
`class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=64,blank=True)
profilePic = models.ImageField(blank=True, null=True, upload_to= "profile/")
phoneNumber = models.CharField(max_length=12,blank=True)
streetAddress = models.CharField(max_length=64,blank=True)`
On my site, the user can edit his profile including the profile picture. To do so, I have a form, where the initial values are the ones initially stored. The forms.py is:
class EditProfile(forms.ModelForm):
def __init__(self, profile, *args, **kwargs):
self.profile = profile
super(EditProfile, self).__init__(*args, **kwargs)
self.fields['name'] = forms.CharField(label='Name:', initial= profile.name,required=False)
self.fields['phoneNumber'] = forms.CharField(label= "Phone Number:", initial= profile.phoneNumber,required=False)
self.fields['streetAddress'] = forms.CharField(label='Street Address and/or Postal Code:', initial= profile.streetAddress,required=False)
self.fields['profilePic'] = forms.ImageField(label='Profile Picture:', initial= profile.profilePic,required=False)
class Meta:
model = Profile
fields = ("name", "phoneNumber","streetAddress", "profilePic")
This part works great, and on my site I can see the stored values. The problem is when I try to edit them and submit the form.
My views.py is:
def settings(request):
user= request.user
if request.method == 'GET':
userProfile = Profile.objects.get(user=user)
f1= UserProfile(user=request.user)
f2= EditProfile(profile=userProfile)
return render(request, 'listings/settings.html', {'form': f1,'form2': f2})
elif request.method == 'POST':
userProfile = Profile.objects.get(user=user)
f1= UserProfile(user=request.user)
f2= EditProfile(profile=userProfile)
name= request.POST["name"]
phoneNumber = request.POST["phoneNumber"]
streetAddress = request.POST["streetAddress"]
Profile.objects.filter(user=user).update(name= name, phoneNumber = phoneNumber, streetAddress = streetAddress)
if "profilePic" in request.FILES:
image1=request.FILES["profilePic"]
fs1=FileSystemStorage()
fs1.save(image1.name, image1)
userProfile.profilePic = image1
userProfile.save()
else:
userProfile.profilePic.delete()
messages.success(request, 'Your profile has been updated!')
return redirect("/settings")
Everything gets edited with no issues except for the imageFile. If I upload the file, it works and the image is updated. However, if I make no changes to the imageFile (i.e. I want to keep the same image), the request.FILES is empty, and then the code goes to the else statement and deletes the existing profilePic.
My question is that the I can see the initial profile picture on my site, so the forms.py is working, but why isn't it being submitted along with the rest of the form?

Your question is a bit confusing, but it seems that you are trying to reinvent the wheel. If you want to have the "initial" data reinserted into the form, you should use the native instance parameter. You can use it as such:
profile = Profile.objects.get(user=user)
# This can be in your GET
profile_form = EditProfile(instance=profile)
# This can be in your POST
profile_form = EditProfile(request.POST, request.FILES, instance=profile)
profile_form.save()

Related

Django not adding a string to models

I am having a problem after I restarted my project from scratch
I can add a value manually to my django model, but when it comes from a variable the user entered, it only pass a blank string..
Some pictures of the logs to be more explicit:
Process:
So, I am having a simple model Tech and I have a page where you can add a new name to Tech model.
I enter the name (here i entered the name ede dede), click add, then i send it to the backend using AJAX.
In the shell in VSCODE I see I received the element, but when I add it to my django model Tech, and then print the new object in Tech, it has an ID, everything, but the name is a blank string ""
Moreover, When i print it in my python code, it doesnt even give me the queryset, i have nothing.
How come?
Here is a piece of my code
VIEWS.PY:
#ajax_required
#require_http_methods(["POST"])
def AddNewEmployee(request):
newtechname = request.POST.get('new_employee').title()
response_data = {}
print('new employee: '+newtechname)
print(type(newtechname))
if Tech.objects.filter(name=newtechname).exists():
response_data['success'] = False
response_data['result'] = 'This name already exists'
return HttpResponse(
json.dumps(response_data),
content_type="application/json"
)
else:
techname = Tech(name=newtechname)
techname = Tech(selected=True) #add new tech to model
techname.save() #save new name to model
response_data['success'] = True
response_data['result'] = 'Added a new teammate successfully!'
response_data['tech_id'] = techname.id #get new name id from model
response_data['tech_name'] = techname.name
response_data['tech_selected'] = techname.selected
print(techname)
return HttpResponse(
json.dumps(response_data),
content_type="application/json"
)
MODELS.PY
class Tech(models.Model):
name = models.CharField(max_length=200)
selected = models.BooleanField(default=False)
def __str__(self):
return self.name
JS:
$('#add-employee').on('submit',function(e){
e.preventDefault();
if(e.target.getAttribute('id')==('add-employee')){
console.log('form submitted!'); //sanity check
AddNewEmployee();
}
});
function AddNewEmployee(){
console.log('AddNewEmployee is working!');
console.log($('#addtech_id').val()); //get the input value from input id
const addemployee_form_url = $('#add-employee').attr('action'); //get the form url
new_employee = $('#addtech_id').val(); // data sent with the post request
console.log(typeof new_employee);
let request_data = {
'new_employee': new_employee,
'csrf_token':csrftoken
}
$self = $(this)
$.ajax({
url : addemployee_form_url, //endpoint
type : "POST", //httpmethod
data : request_data,
//handle a successful response
success : function(response){
$('#addtech_id').val(''); //remove the value from the input
console.log(response); // log the returned json to the console
console.log("A connexion to the backend has been established with success!"); // sanity check
//Add to selected list
if (response['success']){
AddToSelectedList(response['tech_id'], response['tech_name']);
$('#results').html("<h5><div class='alert-box alert radius' data-alert style='color:green;'>"+response['result']+"</div><h5>");
}
else{
$('#results').html("<h5><div class='alert-box alert radius' data-alert style='color:red;'>This name is already in the list!</div><h5>");
}
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
$('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
" <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
What I dont understand is, why is it printing (in views.py) newtechname correctly, which i can even see its type is a string so no problem, then, it passes an empty string to Tech model when techname = Tech(name=newtechname)
Thanks for your help!
The problem is here
else:
techname = Tech(name=newtechname)
techname = Tech(selected=True) #add new tech to model
techname.save() #save new name to model
You are trying to create an object that does not exist as Tech(name=newtechname) doesn't create the object, you can use that after using Tech.objects.create()
So in your case changing that with the traditional objects.create() has resolved the issue.

Redirect to "next" after Google Login. {Flask}

Needing a little help in here:
Context: I am able to log in using email no problem. Redirect and url_for working flawlessly.
When I login with google, though... It is logging in, but not redirecting, thus, not reloading the page, not showing the logout button and so on.
relevant code:
python flask authorized login is "http://localhost:5000/oauth2callback":
btw: I know I shouldn't use google's id, I am still testing it.
#app.route('/oauth2callback/<id>/<nome>/<email>', methods=['POST'])
def oauth2callback(id, nome, email):
#print(f'o ID é {id}, o nome é {nome} e o email é {email}')
try:
if User().query.filter_by(email = email).first():
usuario_google = User().query.filter_by(email = email).first()
print(usuario_google)
login_user(usuario_google)
print('usuario logado')
return redirect(url_for('home', next=request.url))
else:
sessao_google = User(username=email, email=email, nome=nome)
senhas_google = Senha(senha='')
db.session.add(sessao_google)
db.session.commit()
db.session.add(senhas_google)
db.session.commit()
print('Registrado')
return redirect(url_for('login', next=request.url))
except Exception as e:
raise redirect(url_for('login'))
finally:
pass
return redirect(url_for('home'))
I will add javascript just in case:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var xhttps = new XMLHttpRequest();
var novaurl = 'http://localhost:5000/oauth2callback/'+profile.getId()+'/'+profile.getName()+'/'+profile.getEmail();
console.log(novaurl)
xhttps.open('POST', novaurl);
xhttps.send();
}
Thank you for any ideas/help.

Django invoice model formset

I am trying to create an invoice form. I am trying to use a formset because the products will be added more than once in the sales process. I am constantly failing in form creation.
My Models:
class Fatura(models.Model):
musteri = models.ForeignKey(CariModel, on_delete=models.CASCADE, blank=False)
fatura_tarihi = models.DateField(auto_now=True, blank=False)
fatura_numarasi = models.CharField(max_length=36, default=fatura_numarasi)
odeme_tarihi = models.DateField(auto_now=False, blank=True)
def __str__(self):
return "{} - {}".format(self.musteri, self.fatura_numarasi)
class FaturaUrunler(models.Model):
fatura = models.ForeignKey(Fatura, on_delete=models.CASCADE, blank=False)
baslik = models.CharField(max_length=128, blank=False)
urun = models.CharField(max_length=128, blank=False)
miktar = models.DecimalField(max_digits=12, decimal_places=3, default=1)
fiyat = models.DecimalField(max_digits=12, decimal_places=3)
vergi = models.CharField(choices=KDV, default=18, max_length=5)
My Views:
def index(request):
class GerekliFormlar(BaseFormSet):
def __int__(self, *args, **kwargs):
super(GerekliFormlar,self).__init__(*args, **kwargs)
self.queryset = Fatura.object.none()
UrunlerFormset = formset_factory(UrunForm, max_num=0, formset=GerekliFormlar)
if request.method == 'POST':
fatura_form = FaturaForm(request.POST)
urunler_formset = UrunlerFormset(request.POST, request.FILES)
if fatura_form.is_valid() and urunler_formset.is_valid():
fatura = fatura_form.save()
for form in urunler_formset.forms:
urunler = form.save()
urunler.fatura = fatura
urunler.save()
return HttpResponse("tesekkürler")
else:
fatura_form = FaturaForm()
urunler_formset = UrunForm()
c = {
'fatura_form': fatura_form,
'urunler_formset': urunler_formset
}
c.update(csrf(request))
return render_to_response('anasayfa_gecici.html', c)
I would like to make customer selection and product addition within the form. Simple billing system
In your view you were instantiating a form UrunForm() for GET requests and a formset UrunlerFormset() for POST requests. You should use a UrunlerFormset in both cases.
if request.method == 'POST':
fatura_form = FaturaForm(request.POST)
urunler_formset = UrunlerFormset(request.POST, request.FILES)
...
else:
fatura_form = FaturaForm()
urunler_formset = UrunlerFormset()

Get error or an empty value while trying for passing id from django template to reactjs

I am getting an error saying unexpected token while trying for passing id from django template to reatjs for uploading multiple images to its associated foreign key object. The error is shown as unexpected token }. In depth it is shown as
in console
var uploadUrl = {
url:
};
What i am trying to do is , I have created a listing page with multiple form and it is entirely developed using reactjs. I want user to fill the data about room and upload multiple images related to their room. There are two models one with room info and another gallery(multiple image is associated with one rent). I wanted the uploaded images be associated with its rent so i coded it as below
urls.py
urlpatterns = [
url(r'^add/$', AddView.as_view(), name="add"),
url(r'^add/space/$', AddSpaceView.as_view(), name="addSpace"),
url(r'^upload/image/(?P<pk>\d+)/$', ImageUpload, name="ImageUpload"),
]
views.py
def ImageUpload(request,pk=None): // for saving images only to its asscoiated rent
if request.POST or request.FILES:
rental = Rental.objects.get(id=pk)
for file in request.FILES.getlist('image'):
image = GalleryImage.objects.create(image=file,rental=rental)
image.save()
return render(request,'rentals/add.html')
class AddView(TemplateView): // for listing page
template_name = 'rentals/add.html'
class AddSpaceView(View): // for saving data to database except image
def post(self,request,*args,**kwargs):
if request.POST:
rental = Rental()
rental.ownerName = request.POST.get('ownerName')
rental.email = request.POST.get('email')
rental.phoneNumber = request.POST.get('phoneNumber')
rental.room = request.POST.get('room')
rental.price = request.POST.get('price')
rental.city = request.POST.get('city')
rental.place = request.POST.get('place')
rental.water = request.POST.get('water')
rental.amenities = request.POST.get('amenities')
rental.save()
return HttpResponseRedirect('/')
listing.js(ajax code for uploading multiple image)
var image = [];
image = new FormData(files);
$.each(files,function(i,file){
image.append('image',file);
});
$.ajax({
url:"/upload/image/", // want to used id over here that is passed from add.html script tag so that image will be uploaded to its associated foriegn key object
data:image,
contentType:false,
processData:false,
type:'POST',
mimeType: "multipart/form-data",
success: function(data) {
console.log('success');
}
});
}
add.html page
<div id="listing">
</div>
{% include 'includes/script.html'%}
<script type="text/javascript">
var uploadUrl = {
url: {% for rental in object_list %} { "id": {{ rental.id }} } {% endfor %} // here is an error
};
console.log('url is', url);
$(function() {
app.showListingSpaceForm("listing");
});
</script>
The code might explained what i was trying to achieve. If models.py is also required for more scrutiny then i will update it.
You're missing a fundamental piece: TemplateView has no concept of object_list, you have to populate it yourself. If your view is simple enough use ListView and set your model property. If not, you have to manually populate the object list, something like this:
def get_context_data(self, **kwargs):
context['object_list'] = MyModel.objects.all()
That was just an example to set you on the right path.

django - valueError

I'm developing a web application where I'm stuck with a problem in one feature. You can check it out here http://qlimp.com You can also use this for username/password: dummy/dummy
After login, please click the link Go to cover settings You will see a palette where you can upload images, enter some text.
When you upload the image, I've written an ajax request in jQuery which uploads the image to the server and shows fullpage background preview of that image.
JQuery
$('#id_tmpbg').live('change', function()
{
$("#ajax-loader").show();
$("#uploadform").ajaxForm({success: showResponse}).submit();
});
function showResponse(responseText, statusText, xhr, $form) {
$.backstretch(responseText)
$("#ajax-loader").hide();
}
So the problem here is, when I upload the image, it shows
ValueError at /cover/
The view cover.views.backgroundview didn't return an HttpResponse object.
Request Method: POST Request URL: http://qlimp.com/cover/
I'm actually returning HttpResponse object in views.
Views.py:
#login_required
def backgroundview(request):
if request.is_ajax():
form = BackgroundModelForm(request.POST, request.FILES)
if form.is_valid():
try:
g = BackgroundModel.objects.get(user=request.user)
except BackgroundModel.DoesNotExist:
data = form.save(commit=False)
data.user = request.user
data.save()
else:
if g.tmpbg != '' and g.tmpbg != g.background:
image_path = os.path.join(settings.MEDIA_ROOT, str(g.tmpbg))
try:
os.unlink(image_path)
except:
pass
data = BackgroundModelForm(request.POST, request.FILES, instance=g).save()
return HttpResponse(data.tmpbg.url)
else:
form = BackgroundModelForm()
return render_to_response("cover.html", {'form': form}, context_instance=RequestContext(request))
Models.py:
class BackgroundModel(models.Model):
user = models.OneToOneField(User)
background = models.ImageField(upload_to='backgrounds', null=True, blank=True)
tmpbg = models.ImageField(upload_to='backgrounds', null=True, blank=True)
class BackgroundModelForm(ModelForm):
class Meta:
model = BackgroundModel
exclude = ('user','background')
But these things are working on my computer(save the image and shows the background preview) but not in the production server. Why is it so?
I've uploaded the same code to the server.
Could anyone help me? Thanks!
You are not returning a response if the form is valid.

Categories

Resources