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.
Related
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 2 models:
models.py:
class Item(models.Model):
name = models.CharField(max_length=100)
price = models.FloatField(max_length=20)
shelfLife = models.BooleanField()
def __str__(self):
return self.name
#property
def shL(self):
temp = "Doesnt' have shelf life"
if(self.shelfLife):
temp = "Does have sehlf life"
return temp
class Order(models.Model):
num = models.CharField(max_length=20)
date = models.DateField()
items = models.ManyToManyField(Item)
def __str__(self):
return self.num
according to this doc I can do:
views.py:
elif request.method == "POST":
list_items = request.POST.getlist('arr[]') # get list of items
order_num = request.POST.getlist('o_n') # get order num
order_date = request.POST.getlist('o_d') # get order date
order = Order(num=order_num[0], date=order_date[0])
order.save()
for i in range(len(list_items)):
item_name = str(list_items[i])
item = Item.objects.filter(name=item_name)
order.items.add(item)
To fetch each item that I need, I loop through the list_items list of strings and filter each object request by this string and then just add the item to the many-to-many field of the order model.
In addition, when I fetch
item = Item.objects.filter(name="Salad")
the returned QuerySet is not empty, however, if I pass a string variable to the name filter it returns an empty QuerySet.
I would appreciate any help!
Thanks
EDIT:
As #Willem Van Onsem sudjested I chaned my views.py to:
elif request.method == "POST":
list_items = request.POST.getlist('arr[]') # get list of items
order_num = request.POST.getlist('o_n') # get order num
order_date = request.POST.getlist('o_d') # get order date
order = Order(num=order_num[0], date=order_date[0])
order.save()
items = Item.objects.filter(name__in=list_items)
order.items.add(*items)
However, I still get a QuerySet items as an empty QuerySet.
I have checked the request variable list_tems and it is a list of strings (it's not empty).
I tested it by creating an array of Strings
arr=["Salad", "Chocolate"]
and paste it as a filter
items = Item.objects.filter(name__in=arr)
order.items.add(*items)
to the QuerySet and it works - QuerySet object items is not empty and it writes the right data to the DB.
index.html:
$(document).on('click','.btn-create-order',function(){
$.ajax({
method: "GET",
contentType: "application/json",
url: "{% url 'order-items api' %}",
success: function(data){
var index = 1;
data.forEach(element => {
$('#multyItemSelect').append("<option value='" + index + "' id='" +index+ "'> "+ element['fields'].name+"</option>")
index++;
});
},
error: function(jqXHR, textStatus, errorThrown){}
})
})
$('.order-new-submit').click(function(){
var order_num = $('#InputNumber').val()
var order_date = $('#InputDate').val()
var item_selected = $('#multyItemSelect').val() // number
var arr = [] // arr for the item names
var index = 0;
item_selected.forEach(e => {
arr[index] = $('#' + e).html()
index++
});
console.log(order_date)
// DEBUGIN
// arr.forEach(e => {
// console.log(e)
// });
// END DEBUGIN
$.ajax({
method: "POST",
url: "{% url 'order-items api' %}",
data: {'arr[]': arr,
'o_n' : order_num,
'o_d' : order_date},
success: function(data){
},
error: function(jqXHR, textStatus, errorThrown){}
})
})
Thanks to #Willem Van Onsem the issue has been found:
print(list_items)
prints values with space at the beginning:
[' Salad', ' Beef Stake ', ' Chocolate']
item in order.items.add(…) needs to be a model object, or the primary key of that model, but not a queryset. You can however make use of iterable unpacking to pass the items wrapped in the QuerySet as individual parameters:
for i in range(len(list_items)):
item_name = str(list_items[i])
items = Item.objects.filter(name=item_name)
order.items.add(*items) # ← with an asterisk (*)
You can boost efficiency by fetching all the Items in one query with:
items = Item.objects.filter(name__in=[str(x) for x in list_items])
order.items.add(*items)
Hi everyone I want to save the html array for dynamic inputs into the database using django, I have three dynamic inputs on my form, here is my code:
Views.py
def generatescripts(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = GenerateScriptsForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
Step = request.POST.getlist('Step')
for el in Step:
form.save()
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = GenerateScriptsForm()
return render(request, 'page/generatescripts.html', {'form': form})
forms.py
from django import forms
from .models import Steps
class GenerateScriptsForm(forms.ModelForm):
class Meta:
model= Steps
fields = "__all__"
models.py
from django.db import models
# Create your models here.
class Steps(models.Model):
Step = models.CharField(max_length=200,default='0')
Description = models.CharField(max_length=200,default='0')
Result = models.CharField(max_length=200,default='0')
multiple inputs with the same name and I cant save with my code, this code only save one value from the array
generatescripts.html
<input type="button" value="Preview form" class="add" id="preview" />
<input type="button" value="Add a Step" class="add" id="add" />
<script>
$(document).ready(function() {
$("#add").click(function() {
var lastField = $("#buildyourform div:last");
var intId = (lastField && lastField.length && lastField.data("idx") + 1) || 1;
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + intId + "\"/>");
fieldWrapper.data("idx", intId);
var step = $("<input type=\"text\" name= \"Step\" placeholder= \"Step\" class=\"fieldname\" />");
var description = $("<input type=\"text\" name= \"Description\" placeholder= \"description\" class=\"fieldname\" />");
var expectedresult = $("<input type=\"text\" name= \"Result\" class=\"fieldname\" />");
var fType = $("<select class=\"fieldtype\"><option value=\"checkbox\">Checked</option><option value=\"textbox\">Text</option><option value=\"textarea\">Paragraph</option></select>");
var removeButton = $("<input type=\"button\" class=\"remove\" value=\"-\" />");
removeButton.click(function() {
$(this).parent().remove();
});
fieldWrapper.append(step);
fieldWrapper.append(description);
fieldWrapper.append(expectedresult);
fieldWrapper.append(fType);
fieldWrapper.append(removeButton);
$("#buildyourform").append(fieldWrapper);
});
$("#preview").click(function() {
$("#yourform").remove();
var fieldSet = $("<fieldset id=\"yourform\"><legend>Your Form</legend></fieldset>");
$("#buildyourform div").each(function() {
var id = "input" + $(this).attr("id").replace("field","");
var label = $("<label for=\"" + id + "\">" + $(this).find("input.fieldname").first().val() + "</label>");
var input;
switch ($(this).find("select.fieldtype").first().val()) {
case "checkbox":
input = $("<input type=\"checkbox\" id=\"" + id + "\" name=\"" + id + "\" />");
break;
case "textbox":
input = $("<input type=\"text\" id=\"" + id + "\" name=\"" + id + "\" />");
break;
case "textarea":
input = $("<textarea id=\"" + id + "\" name=\"" + id + "\" ></textarea>");
break;
}
fieldSet.append(label);
fieldSet.append(input);
});
$("body").append(fieldSet);
});
});
</script>
<input type="submit" />
</form>
{% endblock %}
I just read your view function, change it to this:
def generatescripts(request):
if request.method == 'POST':
Steps = request.POST.getlist('Step')
Results = request.POST.getlist('Result')
Descriptions = request.POST.getlist('Description')
# FIXME: number of each field should equal
c = min([len(Steps), len(Results), len(Descriptions)])
for i in range(c):
# create a form instance and populate it with data from the request:
form = GenerateScriptsForm({'Step': Steps[i], 'Result': Results[i], 'Description': Descriptions[i]})
# check whether it's valid:
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = GenerateScriptsForm()
return render(request, 'page/generatescripts.html', {'form': form})
I have a save method on my model which I would like to use to validate the fields (I did this in my views before but it was just messy!). I'm saving an object rather than a form because I was having some difficulties with the form validation.
I haven't used save methods before, but I assume they trigger when you use the .save() command? Mine isn't triggering at all... Also from what I understand a clean() method is run for forms when you use is_valid(), so isn't useful for me here?
Here is my view that saves an object using ajax
#login_required
def createtimesheet(request):
if request.method == "POST":
print "creating timesheet"
# Get the person from the previous view
person_object = request.session.get('person')
person = Person.objects.get(id=person_object)
# get the POST data
start_date = request.POST.get('datestart')
end_date = request.POST.get('dateend')
start_date_formatted = datetime.strptime(start_date, "%m/%d/%Y")
end_date_formatted = datetime.strptime(end_date, "%m/%d/%Y")
start_date_print = start_date_formatted.strftime("%B")[0:3] + ". " + start_date_formatted.strftime("%d") + ", " + start_date_formatted.strftime("%Y")
end_date_print = end_date_formatted.strftime("%B")[0:3] + ". " + end_date_formatted.strftime("%d") + ", " + end_date_formatted.strftime("%Y")
response_data = {}
# create our messages
message = ""
error = ""
todays_date = datetime.now()
print_date = todays_date.strftime("%A")
# now we can create the timesheet!
peach = TimeSheet(start_date=start_date_formatted, end_date=end_date_formatted, person_id=person)
# need an if valid.....?
peach.save()
message = "Created new timesheet"
response_data['startdate'] = start_date_print
response_data['enddate'] = end_date_print
response_data['status'] = peach.status
print response_data
context = {
"person": person,
"message": message,
"error": error,
"print_date": print_date,
"todays_date": todays_date,
}
return JsonResponse(response_data)
And here is where I have attempted to write a save method... I'm planning to have a much longer validation function to check if the dates fall on certain days, but for now I just want to get this to work.
class TimeSheet(models.Model):
O = "Open"
S = "Submitted"
A = "Approved"
R = "Needs review"
STATUS_CHOICES = (
(O, "Open"),
(S, "Submitted"),
(A, "Approved"),
(R, "Needs Reviewing"),
)
start_date = models.DateField()
end_date = models.DateField()
person_id = models.ForeignKey(Person)
status = models.CharField(max_length= 50, default="Open", choices=STATUS_CHOICES)
submitted_id = models.IntegerField(default=0)
approved_id = models.IntegerField(default=0)
submitted_date = models.DateTimeField(auto_now_add=True, blank=True)
approved_date = models.DateTimeField(auto_now_add=True, blank=True)
# def __str__(self):
# return self.id
def get_absolute_url(self):
return reverse('tande:timesheet', kwargs={'id': self.id})
def __init__(self, *args, **kwargs):
print "initiating a timesheet"
super(TimeSheet, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
print "something is trying to save!"
ok_to_continue = True
start_date = self.start_date
end_date = self.end_date
if ok_to_continue:
if end_date < start_date:
error = "Start date must be before end date"
ok_to_continue = False
if ok_to_continue:
super(TimeSheet, self).save(*args, **kwargs)
else:
print "def save did not work"
Thanks!
Edit: here is the ajax call
$( document ).ready(function() {
$('#timesheet-form').on('submit', function(event){
event.preventDefault();
console.log("add a timesheet");
createtimesheet();
});
function createtimesheet() {
console.log("create timesheet is working!")
$.ajax({
url : "{% url 'tande:createtimesheet' %}",
type: "POST",
data: { datestart : $('#start').val(), dateend : $('#end').val()},
success : function(json) {
$('#start').val('');
$('#end').val('');
console.log(json);
var html = '<tr><td>'+json.startdate+'</td><td>'+json.enddate+'</td><td>'+json.status+'</td><</tr>';
console.log("success");
// $('div#talk').html(html);
$('#timesheet-list').append(html);
console.log(html)
overlay();
},
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("uh oh");
}
});
};
})
URLs:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^people/$', views.people, name='people'),
url(r'^people/create_person/$', views.create_person, name='create_person'),
url(r'^(?P<person_id>[0-9]+)/person/$', views.person, name='person' ),
url(r'^person/createtimesheet/$', views.createtimesheet, name='createtimesheet' ),
url(r'^(?P<timesheet_id>[0-9]+)/person/timesheet/$', views.timesheet, name='timesheet' ),
]
form id didn't match the id in the ajax call...
id in html is 'create-timesheet-form' and ajax was calling 'timesheet-form'
-.-
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?