how to use |safe in Rich Text Field with django to json
enter image description here
enter image description here
**models
**```
class Question(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
# image = models.FileField(upload_to = "files/images", blank=True, null=True)
# question = models.CharField(max_length=500)
question= RichTextField()
answer = models.IntegerField()
option_one = models.CharField(max_length=500)
option_two = models.CharField(max_length=500)
option_three = models.CharField(max_length=500 , blank=True)
option_four = models.CharField(max_length=500 , blank=True)
is_preview = models.BooleanField(default = False)
marks = models.IntegerField(default=1)
def __str__(self):
return self.question
def get_questions(self):
questions = list(self.raw_questions.all())
random.shuffle(questions)
return questions[:self.number_of_questions]
class Meta:
verbose_name_plural = 'Quizes'
views
def api_question(request , id):
raw_questions = Question.objects.filter(course =id ,is_preview=True)
questions = []
for raw_question in raw_questions:
question = {}
question['id'] = raw_question.id
question['question']= raw_question.question
# question['image'] = raw_question.question
question['answer'] = raw_question.answer
question['marks'] = raw_question.marks
options = []
options.append(raw_question.option_one)
options.append(raw_question.option_two)
# options.append(raw_question.image)
if raw_question.option_three != '':
options.append(raw_question.option_three)
if raw_question.option_four != '':
options.append(raw_question.option_four)
question['options'] = options
questions.append(question)
random.shuffle(questions)
def take_quiz(request , id):
Active = Course.objects.all()
context = {'id' : id,'active':Active}
return render(request , 'quiz2.html' , context)
>! html
<form #submit.prevent="handleSubmit()"'>
** [[index + 1 ]].[[ question.question|safe ]]
**
<br>
<div v-for="(option , i) in question.options" style="font-size:18px;"> [[option]]</h4>
<p style="text-align: left; color: var(--primary-color);">Prof. AboRashad<br></p>
<!--<h5 style="text-align: right; color: var(--primary-color);">created by : AboRashad<br></h5>-->
<!--<h2 style="text-align: center; color: #5bc1ac54;">created by : AboRashad<br></h2>-->
<p :id="'show_message-'+question.id" ></p>
<!--<h3 style="text-align: right; color:#5bc1ac54;">created by : AboRashad<br></h3>-->
</div><br>
</div> <button class="btn btn-danger" type="submit" style='width: 100%'>Send</button>
</form>
<br><br><br><br><br><br>
</div>
var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: {
message: 'Hello Vue!',
course_id: '{{id}}',
questions: [],
solutions: []
},
methods: {
greet: function (name) {
console.log('Hello from ' + name + '!')
},
check(question_index, option_index, id) {
var question = this.questions[question_index]
var element = document.getElementById(`show_message-${id}`)
// if((option_index + 1).toString()==question.answer){
// element.classList="text-success mt-3"
// element.innerHTML ="Right Answer "
// }else{
// element.classList="text-danger mt-3"
// element.innerHTML ="weong Answer "
// },
var radios = document.querySelectorAll(`#radio-${id}`)
for (var i = 0; i < radios.length; i++) {
radios[i].disabled = true
}
var solution = {
'question_id': id,
'option': option_index + 1
}
this.solutions.push(solution)
},
handleSubmit() {
fetch('/api/check_score', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data : JSON.stringify(this.solutions),
course_id : this.course_id
})
})
.then(res => res.json())
.then(result => {
console.log(result)
window.location = '/view_score'
})
}
},
mounted() {
fetch(`/api/${this.course_id }`)
.then(res => res.json())
.then(result => {
this.questions = result
})
}
});
Related
I kept getting this error each time i try to create a todo list from the todo app i just developed:
DataError
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type integer: "create"
LINE 3: WHERE todolists.id = 'create'
^
[SQL: SELECT todolists.id AS todolists_id, todolists.name AS todolists_name
FROM todolists
WHERE todolists.id = %(pk_1)s]
[parameters: {'pk_1': 'create'}]
(Background on this error at: https://sqlalche.me/e/14/9h9h)
here is my code: index.html
<body>
<div class="lists-wrapper">
<h4>Lists Items</h4>
<form action="/lists/create" method="POST" id="list-form">
<label for="todolists">Create List: </label><br>
<input type="text" name="name" id="name" data-id="{{active_list.id}}" placeholder="Create list">
<button type="submit" >Create</button>
</form>
<ul id="lists">
{% for list in lists %}
<li>
<input type="checkbox" id="complete" class="list-check-completed" data-id="{{list.id}}">
{{list.name}}
<button class="delete-list" data-id="{{list.id}}">✗</button>
</li>
{% endfor %}
</ul>
</div>
<div class="todos-wrapper">
<h4>Todo Items</h4>
<form action="/todos/create" method="POST" id="todo-form">
<input type="hidden" id="list_id" value="{{active_list.id}}">
<label for="description">Create Task</label><br>
<input type="text" name="description" id="description" placeholder="Create todos">
<input type="submit" value="Create">
</form>
<!-- <h5>{{active_list.name}}</h5> -->
<div id="error" class="hidden">Something went wrong!</div>
<ul id="todos">
{% for todo in todos %}
<li>
<input type="checkbox" data-id="todo.id" class="todo-check-completed" name="complete" id="complete" {% if todo.completed %} checked {% endif %}>
{{todo.description}}
<button class="delete-todo" data-id="{{todo.id}}" >✗</button>
</li>
{% endfor %}
</ul>
</div>
<script>
const listcheckboxes = document.querySelectorAll('.list-check-completed');
for(let i = 0; i < listcheckboxes.length; i++) {
const checkbox = listcheckboxes[i];
checkbox.onchange = function() {
if(e.target.checked){
const listId = e.target.dataset['id'];
fetch('/lists/' + listId + '/set-completed', {
method: 'POST',
headers: {
'Content-Type' : 'application.json'
}
})
.then(function(jsonResponse) {
document.getElementById('error').className = 'hidden'
const todocheckboxes = document.querySelectorAll('.todo-check-completed');
for(let i = 0; i < todocheckboxes.length; i++) {
const checkbox = todocheckboxes[i];
checkbox.checked = true;
}
})
.catch(function(){
document.getElementById('error').className = '';
})
}
}
}
const deleteListbtns = document.querySelectorAll('.delete-list');
for(let i = 0; i < deleteListbtns.length; i++) {
const btn = deleteListbtns[i];
btn.onclick = function (e) {
const listId = e.target.dataset['id'];
console.log('Delete event:', e);
fetch('/lists' + listId + '/delete-list', {
method: 'DELETE',
}).then(function() {
console.log('Parent?', e.target);
const item = e.target.parentElement;
item.remove();
document.getElementById('error').className = 'hidden';
window.location.reload() = true;
}).catch(function() {
document.getElementById('error').className = '';
})
}
}
document.getElementById('list-form').onsubmit = function (e) {
e.preventDefault();
fetch('/lists/create', {
method: 'POST',
body: JSON.stringify({
'name': document.getElementById('name').value,
}),
headers: {
'Content-Type':'application.json'
}
})
.then(function(response){
return response.json()
})
.then(function(jsonResponse){
const listItem = document.createElement('li');
listItem.innerHTML = jsonResponse['name'];
document.getElementById('lists').appendChild(listItem);
document.getElementById('error').className = 'hidden';
window.location.reload(true);
})
.catch(function() {
document.getElementById('error').className = '';
})
}
const todocheckboxes = document.querySelectorAll('.todo-check-completed');
for(let i = 0; i < todocheckboxes.length; i++){
const todocheckbox = todocheckboxes[i];
todocheckbox.onchange = function (e) {
console.log('checked: ', e)
const todoId = e.target.dataset['id'];
const newCompleted = e.target.checked;
fetch('/todos/' + todoId + '/set-completed', {
method: 'POST',
body: JSON.stringify({
'completed': newCompleted,
}),
headers: {
'Content-Type':'application/json'
}
})
.then(function(jsonResponse) {
document.getElementById('error').className = 'hidden';
})
.catch(function() {
document.getElementById('error').className = ' ';
})
}
}
const deletetodoBtns = document.querySelectorAll('.delete-todo');
for(let i = 0; i < deletetodoBtns.length; i++) {
const deletetodoBtn = deletetodoBtns[i];
deletetodoBtn.onclick = function (e) {
const todoId = e.target.dataset['id'];
fetch('/todos/' + todoId + '/delete-todos', {
method:'DELETE'
})
.then(function(e) {
document.getElementById('error').className = 'hidden';
const item = e.target.parentElement;
item.remove();
window.location.reload() = True;
})
.catch(function() {
document.getElementById('error').className = ' ';
})
}
}
document.getElementById('todo-form').onsubmit = function (e) {
e.preventDefault();
fetch('/todos/create', {
method: 'POST',
body: JSON.stringify({
'description': document.getElementById('description').value,
'list_id': document.getElementById('list_id').value
}),
headers: {
'Content-Type':'application.json'
}
})
.then(function(response) {
return response.json()
})
.then(function(jsonResponse) {
const listItem = document.createElement('li');
listItem.innerHTML = jsonResponse.description;
document.getElementById('todos').appendChild(listItem);
document.getElementById('error').className = 'hidden';
window.location.reload(true);
})
.catch(function() {
document.getElementById('error').className = '';
})
}
</script>
</body>
</html>
while the app.py
from flask import Flask, jsonify, render_template, abort, url_for, redirect
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import sys
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres#localhost:5432/todoapp_gig'
app.config['SQLALCHEMY_TRACK_MODIFICATION'] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db)
class TodoList(db.Model):
__tablename__ = 'todolists'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(), nullable=False)
todos = db.relationship('Todo', backref='list', lazy=True)
def __repr__(self):
return f'<TodoList ID: {self.id} name: {self.name} todos: {self.todos}>'
class Todo(db.Model):
__tablename__ = 'todos'
id = db.Column(db.Integer, primary_key = True)
description = db.Column(db.String(), nullable = False)
complete = db.Column(db.Boolean, nullable=False, default=False)
list_id = db.Column(db.Integer, db.ForeignKey('todolists.id'), nullable=False)
def __repr__(self):
return f'<Todo ID: {self.id} description: {self.description} complete: {self.complete}>'
#app.route('/lists/<list_id>/set-completed', methods = ['POST'])
def set_completed_list(list_id):
error = false
try:
list = Todo.query.get(list_id);
for todo in list.todos:
todo.completed = True
db.session.commit()
except:
db.session.rollback()
error = True
finally:
db.session.close()
if error:
abort(400)
else:
return ' ', 200
#app.route('/lists/<list_id>/delete-list', methods = ['POST'])
def delete_list(list_id):
error = False
try:
list = Todo.query.get(list_id);
for todo in list.todos:
db.session.delete(todo)
db.session.delete(list)
de.session.commit()
except:
db.session.rollback()
error = True
finally:
db.session.close()
if error:
abort(500)
else:
return jsonify({
'success': True
})
#app.route('/lists/create', methods = ['POST'])
def create_list():
error: False
body = {}
try:
name = request.get_json()['name']
todolist = TodoList(name=name)
db.session.add(todolist)
db.session.commit()
body['id'] = todolist.id
body['name'] = todolist.name
except:
db.session.rollback()
error = True
finally:
db.session.close()
if error:
abort(400)
else:
return jsonify(body)
#app.route('/todos/<todo_id>/set-completed', methods = ['POST'])
def set_completed_todos(todo_id):
error: False
try:
todo = Todo.query.get(todo_id)
completed = request.get_json()['completed']
todo.completed = completed
db.session.commit()
except:
db.session.rollback()
error = True
finally:
db.session.close()
if error:
abort(400)
else:
return ' ', 200
#app.route('/todos/<todo_id>/delete-todos', methods = ['POST'])
def delete_todos(todo_id):
error = False
try:
# todo = Todo.query.filter_by(id=todo.id).delete()
todo = Todo.query.get(todo_id)
db.session.delete(todo)
db.session.commit()
except:
db.session.rollback()
error = True
finally:
db.session.close()
if error:
abort(400)
else:
return jsonify({'success': True})
#app.route('/todos/create', methods=['POST'])
def create_todo():
error = False
body={}
try:
description = request.get_json()['description']
list_id = request.get_json()['list_id']
todo = Todo(description = description, completed = False, list_id = list_id)
db.session.add(todo)
db.session.commit()
body['id'] = todo.id
body['complete'] = todo.complete
body['description'] = todo.description
except:
db.session.rollback()
error = True
print(sys.exc_info)
finally:
db.session.close()
if error:
abort(400)
else:
return jsonify(body)
#app.route('/lists/<list_id>')
def get_list_todos(list_id):
lists = TodoList.query.all()
active_list = TodoList.query.get(list_id)
todos = Todo.query.filter_by(list_id=list_id).order_by('id').all()
return render_template('index.html', lists=lists, active_list=active_list, todos=todos)
#app.route('/')
def index():
return redirect(url_for('get_list_todos',))
if __name__ == "__main__":
app.run(host = '0.0.0.0', port = 5000)
Please what am i doing wrong!!! the error keep pointing at this very code:
active_list = TodoList.query.get(list_id)
I tried to create a todolist after rendering my code, but instead it gave me a datatype error of which i cant figure how to correct it.
I don't know what's triggering the error.
To create a post, the user must go through the form for creating posts and upload an image, but I don’t know how to do this.
I tried to send file event.target.files[0] but I received "POST /api/tests/ HTTP/1.1" 400 91
it didn't help, I tried to send event.target.files[0].name but that didn't help either.
TestForm.jsx:
import React, {useState} from 'react';
import axios from "axios";
function TestForm() {
const [testInputs, setTestInputs] = useState({title: '', title_image: '', test_type: ''});
console.log(testInputs);
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
const handleClick = () => {
axios({
method: 'POST',
url: 'http://127.0.0.1:8000/api/tests/',
data: {
author: 1,
title: 'sad',
title_image: testInputs.title_image.name,
test_type: 2,
question: [1, 3, 4],
result: [1, 2]
}
})
}
return (
<div>
<form>
<input onChange={(event) => {setTestInputs({...testInputs, title_image: event.target.files[0]}); console.log(event.target)}} type="file" placeholder='upload'/>
</form>
<button onClick={handleClick}>asd</button>
</div>
);
}
export default TestForm;
models.py
class Test(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
title_image = models.ImageField(default="images/IMG_1270.JPG/", null=True, blank=True, upload_to='titleImages/')
test_type = models.ForeignKey(TestType, on_delete=models.CASCADE)
question = models.ManyToManyField(TestQuestionBlok)
result = models.ManyToManyField(TestResult, blank=True)
def __str__(self):
return self.title
views.py
class TestList(APIView):
def post(self, request, format=None):
serializer1 = TestSerializers(data=request.data)
if serializer1.is_valid():
print(serializer1.data)
return Response(serializer1.data, status=status.HTTP_200_OK)
return Response(serializer1.errors, status=status.HTTP_400_BAD_REQUEST)
#Api
import axios;
const avatarupload = (data, uuid) => {
return axios.post(`endpoint/`, data).then(
(res) => res,
(error) => error.response
);
};
#Store
getAvatar = async (data, cb) => {
const uuid = LocalStorageService.getUuid();
const resp = await avatarupload(data, uuid);
if (resp.status === 200) {
this.setMessage('Successfully Updated');
this.setUser(resp.data);
cb();
} else {
cb(resp.data.error);
}
this.setPicLoading(false);
};
#web page
const handleFileChange = async (event) => {
const data = new FormData();
data.append('avatar', event.target.files[0]);
getAvatar(data, (error) => {
setError(error);
});
setFader(1);
};
<Form.Group controlId='formBasicText'>
<button
className='primary'
type='button'
onClick={handleChangeAvatarClick}
>
CHANGE AVATAR
</button>
<Form.Control
style={{ display: 'none' }}
type='file'
ref={hiddenFileInput}
onChange={handleFileChange}
accept='image/*'
/>
</Form.Group>
I have a project with a model called "List," and a model called "ListItem." There are multiple list items to each list. Here's what I'd like to do. I'd like the user to be able to create a new list with as many items as they deem necessary on one form.
Here's the logic I have so far:
models.py:
class List(models.Model):
team = models.ForeignKey(Team, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class ListItem(models.Model):
team_list = models.ForeignKey(List, on_delete=models.CASCADE)
content = models.TextField()
index = models.IntegerField()
def __str__(self):
return f"{self.team_list} [{self.index}]"
forms.py:
class NewListForm(forms.ModelForm):
name = forms.CharField(max_length=50, label='Card Name')
team = forms.ModelChoiceField(queryset=models.Team.objects.all())
class Meta:
model = models.List
fields = ['name', 'team']
class NewListItemForm(forms.ModelForm):
content = forms.CharField(widget=forms.Textarea,
label='Item', required=True)
class Meta:
model = models.ListItem
fields = ['content']
views.py:
def new_list(request):
context = {
'title': 'New List',
'list_form': NewListForm,
'list_item_form': NewListItemForm,
}
if request.method == 'POST':
list_form = NewListForm(request.POST)
list_item_form = NewListItemForm(request.POST)
if list_form.is_valid() and list_item_form.is_valid():
list_instance = list_form.save()
list_item_instance = list_item_form.save(commit=False)
list_item_instance.team_list = list_instance
list_item_instance.index = 1
list_item_instance.save()
messages.success(request, "List has been created!")
return redirect('home')
else:
messages.error(request, "That list name is already taken")
return render(request, 'lists/new_list.html', context)
This works for creating 1 list and just 1 item. Ultimately, I'd like the user to be able to add as many additional list item forms as is necessary AND have the "index" field of each item on that list increment by 1 with each new list item instance.
Is there some way to loop through each instance of a repeated form and save a unique instance in my db an indefinite number of times?
I don't think you need to increment the index yourself, django should increment it automatically. I used formset_factory and javascript on my template to have the ability to add fields to the form dynamically. I am not very familiar with django or javascript (I'm very early in the learning process), but this is how I got it to work in my case:
models.py
class Instructors(models.Model):
instructors = models.CharField(max_length=60)
injury = models.ForeignKey("Injury", on_delete=models.CASCADE)
forms.py
class InstructorForm(forms.Form):
instructor = forms.CharField(max_length=60, required=False)
InstructorFormset = formset_factory(InstructorForm, extra=1)
views.py (relevant section)
...
formset = InstructorFormset(request.POST)
if formset.is_valid()
for form in formset:
if form.cleaned_data:
instructor = Instructors(
instructors=form.cleaned_data["instructor"],
injury=injury,
)
instructor.save()
...
context = {"formset":formset}
template.html
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
{{ form.instructor }}
<div class="input-group-append">
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type='text/javascript'>
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
console.log(newElement);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
var name = $(this).attr('name');
if (name != undefined) {
console.log(name);
console.log(total);
var name = name.replace('-' + (total-1) + '-', '-' + total + '-');
console.log("next");
};
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('-');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
</script>
I don't remember where I got the js code, but I did not write it and can't take credit for it. Hopefully you have a better understanding than I do, but it works for me as is.
Helloo,
I am following a tutorial to allow User to select Light/Dark Mode using HTML, CSS, JS.
I have following documentation and tutorial but the issue is that the content of the page itself is not showing and I am not sure the reason.
So what I did is I created 2 css files dark and light, and create a mode application with the settings.
I am currently receiving an error:
django.contrib.auth.models.User.setting.RelatedObjectDoesNotExist: User has no setting.
To start here is the base.html
<link id="mystylesheet" href="{% static 'css/app-light.css' %}" type="text/css" rel="stylesheet">
<!-- Mode -->
<div id="mode" class="section" style="padding-top: 1rem; padding-bottom: 3rem;text-align: right">
<button onclick="swapStyle('css/app-light.css')" type="button" class="btn btn-secondary">Light Mode</button>
<button onclick="swapStyle('css/app-dark.css')" type="button" class="btn btn-dark">Dark Mode</button>
</div>
<!-- Mode -->
<script type="text/javascript">
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
var cssFile = "{% static 'css' %}"
function swapStyles(sheet){
document.getElementById('mystylesheet').href = cssFile + '/' + sheet
localStorage.setItem('theme', sheet)
updateTheme(sheet)
}
function loadSettings(){
//Call data and set local storage
var url = "{% url 'mode:user_settings' %}"
fetch(url, {
method:'GET',
headers:{
'Content-type':'application/json'
}
})
.then((response) => response.json())
.then(function(data){
console.log('Data:', data)
var theme = data.value;
if (theme == 'light.css' || null){
swapStyles('light.css')
}else if(theme == 'dark.css'){
swapStyles('dark.css')
}
})
}
loadSettings()
function updateTheme(theme){
var url = "{% url 'mode:update_theme' %}"
fetch(url, {
method:'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
},
body:JSON.stringify({'theme':theme})
})
}
</script>
Here is the model.py
class Setting(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
value = models.CharField(max_length=200)
def __str__(self):
return self.name
here is the views.py
def index(request):
return render(request, 'base.html')
def userSettings(request):
user, created = User.objects.get_or_create(id=1)
setting = user.setting
seralizer = UserSerailizer(setting, many=False)
return JsonResponse(seralizer.data, safe=False)
def updateTheme(request):
data = json.loads(request.body)
theme = data['theme']
user, created = User.objects.get_or_create(id=1)
user.setting.value = theme
user.setting.save()
print('Request:', theme)
return JsonResponse('Updated..', safe=False)
Here is the serializer.py
from .models import *
class UserSerailizer(serializers.ModelSerializer):
class Meta:
model = Setting
fields = '__all__'
Here is urls.py
app_name = 'mode'
urlpatterns = [
path('', views.index, name="index"),
path('user_settings/', views.userSettings, name="user_settings"),
path('update_theme/', views.updateTheme, name="update_theme"),
]
Here is the traceback
Traceback (most recent call last):
File "C:\Users\Ahmed\Desktop\Project\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Ahmed\Desktop\Project\venv\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Ahmed\Desktop\Project\mode\views.py", line 17, in userSettings
setting = user.setting
File "C:\Users\Ahmed\Desktop\Project\venv\lib\site-packages\django\db\models\fields\related_descriptors.py", line 421, in __get__
raise self.RelatedObjectDoesNotExist(
django.contrib.auth.models.User.setting.RelatedObjectDoesNotExist: User has no setting.
You need to handle the case when a user will not have a setting in userSettings function.
def userSettings(request):
user, created = User.objects.get_or_create(id=1)
setting = getattr(user, 'setting', None)
if setting:
seralizer = UserSerailizer(setting, many=False)
return JsonResponse(seralizer.data, safe=False)
else:
return JsonResponse({'message': "User don't have a setting."}, safe=False)
And also make sure that updateTheme function works perfectly. If it doesn't work try following.
def updateTheme(request):
data = json.loads(request.body)
theme = data['theme']
user, created = User.objects.get_or_create(id=1)
setting = Setting.objects.get_or_create(user=user, value=theme, name='a name')
setting.save()
print('Request:', theme)
return JsonResponse('Updated..', safe=False)
Note that in the name field of Setting model you didn't pass null=True. So you have to pass name when creating a setting of a user.
Also in your base.html you are using onclick="swapStyle()" yet your javascript function is function swapStyles(){}. Change this
setting = getattr(user, 'setting', None)
I have been trying to upload multiple images at once but my API takes only one image among the list of images. What might be the reason for not taking all the images ? What have i done wrong?
Here's my code.
urls.py
url(r'^api/', RentalList.as_view()),
url(r'^api/upload/', FileUploadView.as_view()),
url(r'^api/(?P<pk>[0-9]+)/$', RentalDetail.as_view()),
Models.py
class Rental(models.Model):
email = models.CharField(max_length=120,blank=True, null=True)
phoneNumber = models.PositiveIntegerField(blank=False,null=True,
help_text=_("Phone number of contact person"))
listingName = models.CharField(_("Lisitng Name"), max_length=255, blank=False, null=True,
help_text=_("Title of the rental space"))
summary = models.TextField(max_length=500, blank=True, null= True,
help_text=_("Description of the rental space"))
property = models.CharField(_("Property type"),max_length=10,null=True)
price = models.PositiveIntegerField(blank=False,null=True,
help_text=_("Rental price of the space per month"))
city = models.CharField(_("City"), max_length=255, blank=False, null=True,
help_text=_("City of the rental space"))
place = models.CharField(_("Place"), max_length=255, blank=False, null=True,
help_text=_("Place of the rental space"))
phone_image = models.CharField(max_length=2048,blank=True,null=True,
help_text=_("image form of the phone number"))
image = models.FileField(upload_to='upload/',null=True,blank=True)
Views.py
class RentalList(generics.ListCreateAPIView):
serializer_class = RentalSerializer
queryset = Rental.objects.all()
def get(self,request,format=None):
rental = self.get_queryset()
serializer_rental = RentalSerializer(rental,many=True)
return Response(serializer_rental.data)
#permission_classes((IsAdminUser, ))
def post(self,request,format=None):
user=request.user
serializer_rental = RentalSerializer(data=request.data,context={'user':user})
if serializer_rental.is_valid():
serializer_rental.save()
return Response(serializer_rental.data,status=status.HTTP_201_CREATED)
return Response(serializer_rental.errors,status=status.HTTP_400_BAD_REQUEST)
class RentalDetail(generics.RetrieveUpdateDestroyAPIView):
queryset=Rental.objects.all()
serializer_class = RentalSerializer
class FileUploadView(APIView):
parser_classes = (MultiPartParser, FormParser, )
def post(self, request, format=None):
uploaded_file = request.FILES['image']
print('up_file is',uploaded_file)
filename = '/media/upload'
with open(filename, 'wb+') as destination:
for chunk in uploaded_file.chunks():
print('chunk',chunk)
destination.write(chunk)
destination.close()
my_saved_file = open(filename)
return Response(uploaded_file.name, status.HTTP_201_CREATED)
registration.jsx
var RenderPhotos = React.createClass({
getInitialState: function () {
return {
files:[]
};
},
onDrop(files) {
console.log('Received files: ', files);
this.setState({
files: files
});
},
showFiles() {
const files = this.state.files || null;
console.log('files',files);
if (!files.length) {
return null;
}
return (
<div>
<h3>Dropped files: </h3>
<ul className="gallery">
{
files.map((file, idx) => {
return (
<li className="col-md-3" key={idx}>
<img src={file.preview} width={100}/>
<div>{file.name}</div>
</li>
);
})
}
</ul>
</div>
);
},
render: function () {
return (
<div>
<h3>Photos can bring your space to life</h3>
<p>Add photos of spaces to give more insight of your space </p>
<hr/>
<div className="col-md-12">
<form method="post" encType="multipart/form-data">
<Dropzone onDrop={this.onDrop}
style={style}
activeStyle={activeStyle}>
Try dropping some files here, or click to select files to upload.
</Dropzone>
</form>
{this.showFiles()}
</div>
<div className="row continueBtn text-right">
<button className="btn how-it-works pull-left" onClick={this.props.previousStep}>Back</button>
<button className="btn how-it-works" onClick={this.submitRent}>Submit</button>
</div>
</div>
);
},
submitRent: function(e) {
// want to store the data so that when user reverts back to this form the data should be in same previous state
var req = request.post('http://localhost:8000/api/upload/');
var image = [];
image = new FormData();
var that = this;
var index;
for (index = 0; index < that.state.files.length; ++index) {
console.log(that.state.files[index]);
image.append('image',that.state.files[index]);
}
req.send(image);
console.log('req is',req);
req.end((err, res) => {
if (err) {
console.log('error', err);
} else {
console.log('success', res);
}
});
}
});
I have posted all the code thinking that it might be easy for tracing the errors.
Do i need to create ManyToMany field for image?