Django passing user profile data from client to server - javascript

I am using a custom User model with an user profile using a OneToOneField with this structure :
email
password
profile : {
username
avatar
}
It works pretty good for mobile because I just basically send json back and forth, but it's a problem whenever I am using my API with a website because there is no way in html to send json-like data, hence I can't fill the "profile" field without using ajax.
I would prefer to have the possibility to use plain html forms and to use javascript only for client validation and animation not using it for critic functionality such as registration.
I can also use the following structure and then reconstruct a dictionary for the profile server-side but I do feel that's it's not generic enough.
email
password
username
avatar
UserSerializer.py
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
profile = ProfileSerializer(required=True)
class Meta:
model = get_user_model()
fields = ('id', 'email', 'password', 'date_joined', 'profile')
def create(self, validated_data):
#profile_data = validated_data.pop('profile')
password = validated_data.pop('password')
user = get_user_model().objects.create_user(**validated_data)
user.set_password(password)
#user.save()
print(user)
#print(profile_data
ProfileSerializer.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('username',)
So no matter if I am using json or form data, obviously it's waiting for a profile (object) data. I would like to be able to do it using html form.
Any idea how I should approach this ?

If I correctly understood your problem, you may find the Django rest framework useful for this.
The django rest framework have Views that can handle both json and form data and feed them in the same validation mechanism. It basically uses the Content-Type header to choose a parser for the incoming data (more details here). Maybe you may look at what they did or use the library directly.
Hope this helps.

Maybe you can write an ApiView with a FormParser?
See: http://www.django-rest-framework.org/api-guide/parsers/#formparser

Related

Is there a way to take user input from a form and append it to code I already have?

I have html and css code for a basic quiz template. I want to give the user the ability to make their own custom quiz.
Example: I have created my own math quizzes, science quizzes, etc, that the user can take. I am looking for the ability that Users can make their own personal quiz.
You don't append users input to your code. You should have your quiz as a data and let the user update the data by adding their quiz.
The structure of a form looks like this:
<form method = 'post' action='./handleSubmission/'>
<label>Question 1: </label>
<input type='text' class='question' name='question1'>
<label>Answer 1: </label>
<input type='text' class='answer' name='answer2'>
<label>Question 2: </label>
<input type='text' class='question' name='question2'>
<label>Answer 2: </label>
<input type='text' class='answer' name='answer2'>
<button>Submit</button>
</form>
(You can find all the different input types here. You might want another type for multiple choice questions.
When the user clicks on submit, the default behaviour is that the content of the form will be sent as an http request to the action url. if you set post as method, the method will be POST. If you set get as method, the method will be GET.
Now, in order to do something useful with it, there needs to be a server-side script at './handleSubmission/' or whatever url you put in here, that can read the sent data and upload it to some place where you store the data for your quizzes. This can be either a database or a repository containing some files.
I'd go for json files. Because json files can very easily be decoded and used in any web scripting language.
In PHP for example you'd get the content of the form through a special array called $_GET (or $_POST depending on the method).
You'd then have access to 'question1' with $_GET['question1'].
You'd then have to find a way to put that data into a json file.
To use the content of the json files, you can either use a backend script or a frontend script like javascript.
Are you already using a scripting language for the backend such as PHP or Python? Or do you focus on frontend?
If you want to focus on javascript and frontend, this is the alternative:
<form>
//...
<button id='btn-submit'>Submit</button>
</form>
As you can see, i ommited action and method because in this alternative we don't want to send the form to the server. What we'll do is, when the button is clicked, we'll capture the content of the form without refreshing the page, and then send it a Backend-as-a-service like Google Firebase.
const submitButton = document.querySelector('#btn-submit');
submitButton.addEventListener('click', (e) => {
/* important! prevents the default behaviour which is to submit the form */
e.preventDefault();
const data = [];
/* do stuff here to retrieve the data from form like: */
const questionInputs = document.querySelector('.question');
const answerInputs = document.querySelector('.answer');
for(let key in questionInputs){
data[key] = {
question: questionInputs[key].value;
answer: answerInputs[key].value;
}
}
sendToFirebase(data);
});
You'd then have to write the sendToFirebase function.
Firebase requires making an account, starting a project by giving a name etc. Then it gives you the code to put in your app and you can read the documentation about how to upload data to the Realtime Database.
I strongly prefer the first option however. Because i think in this case the Firebase Realtime Database would be a bit cumbersome to use compared to just setting up a small backend script that generates json files.

Best way to send html form to an email address within Django project?

I see contact forms on almost all websites and they make it look easy. Reading on how to do it seems complex, especially since most of the solutions are using php and a server. I don't really know php and I already have four languages in my project and it just gets overwhelming. I want something simple; fill out the details, send to an email, and done.
Fill out name: John Doe
Fill out dob: 6/11/2018
[Submit] (send to example#example.com)
Here is a basic overview of how that could be accomplished.
Use a form with the details:
from django import forms
class ContactForm(forms.Form):
name = ...
birht_date = ...
Use this form in a view, maybe using FormView:
from django.conf import settings
from django.core.mail import send_mail
from django.views.generic.edit import FormView
class ContactView(FormView):
form_class = ContactForm
success_url = '/thanks/'
def form_valid(self, form):
# here you send the email
send_email(
sub='New contact: {}'.format(form.cleaned_data['name']),
msg='This new contact was born {}'.format(form.cleaned_data['birth_date']),
from=settings.SERVER_EMAIL,
to='example#example.com')
return super().form_valid(form)
Maybe this puts you an the right track to solve your situation.

how safe is to pass the 'user' to javascript Ajax in laravel?

I already asked about this situation but when you pass the data directly to the view like this:
you get the user with $user = Auth::user(); and then send it to the view with return view ('somepage')->with('user',$user); the browser will get all user data in the view (uername, password, user_id etc..).
And found out it should be safe. Now I am thinking what if you instead are passing it to a script that is in charge of updating the view?
Like this:
return Response()->json($user);
You are firing a json in the wild that gets into the script as data, so can a third party have access to that json data too?
No, you DO NOT want to pass any sensitive data to a script or through JSON. Both of these resources would be viewable from the client side.
You can however, remove the sensitive data from your object before serializing it to JSON and passing to the browser.
In your Eloquent models, add a $hidden property - this property is an array of attributes that will be removed when serializing the model to JSON.
So, your User model will look like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = ['password'];
}
Then, the password will be removed and not accessible from the client.
Docs: https://laravel.com/docs/5.2/eloquent-serialization#hiding-attributes-from-json

Deleting objects with django framework or javascript/AJAX

I have a page that has a simple form. When I submit this form I am redirected to the same page with the new objects created. I'd like to add inline links to the right of every object created to delete and edit. Would I do this with django or would I use javascript/AJAX to handle this? I'm just a little confused on the approach that I should take. Any suggestions?
Here's what my view currently looks like:
def events(request):
the_user = User.objects.get(username=request.user)
event_list = Event.objects.filter(user=the_user)
if request.POST:
form = EventForm(request.POST)
if form.is_valid():
form.save()
else:
form = EventForm(initial={'user':the_user})
return render_to_response("events/event_list.html", {
"form": form,
"event_list": event_list,
}, context_instance=RequestContext(request))
Usually, you would write another view function, e.g. delete_event(request, event_id) and wire it up in urls.py. Inside the delete view, you would use the provided Model.delete() function to remove the object from the database.
The choice whether to use ajax or not is mostly a matter of taste - you would need to issue a request via javascript to a similar function as I described above, which would take care of the logic.
Some additional overhead is present (when using ajax) in terms of updating the page appropriately.
The proper http verb for deletes would be DELETE, but since this is not usually supported out of the box, you'll use POST.

Django design question: handling different form types between client and server

I'm trying to build a Django app for inputting science data, but am running into problems coming up with an elegant way to describe the possible forms.
I have two models, HCameraImage and MCameraImage that inherit from an Image model. On the site, the user can fill in HTML forms that populate either of these two models. In another words, I'm using HCameraImageForm(request.POST) to populate the model. Once I send it over to the client side, I find myself having to manually keep track of what form type is being sent to Django by appending an imagetype to the POST data:
if request.POST['imagetype'] == "HCameraImage":
form = HCameraImageForm(request.POST)
form.save()
if request.POST['imagetype'] == "MCameraImage":
form = MCameraImageForm(request.POST)
form.save()
...etc
Is there a more elegant way to deal with this? Ideally I want to have some parent base class Image that lets me do:
i = Image()
i.loadFormData(request.POST)
where loadFormData calls the correct derived function.
You could construct a string to instantiate the correct form object. Something like this should work:
import myapp.models
form_class = request.POST['imagetype'] + 'Form'
form_class = getattr(myapp.models, form_class)
form = form_class(request.POST)
form.save()

Categories