Tasty pie multipart post integer field become array - django

I uploading lie with additional fields to DJANGO testy pie and get validation error
If I post file field and char field - char field become from 'test' to '[test]'
If I post also integer field for example 57 it becomes ['57']
I check fron - it's ok
In back request.POST have converted data... Field in model described as small integer field
class SpkPhotoResource(ModelResource):
img = fields.FileField(attribute="filename", null=True, blank=True)
class Meta:
queryset = SpkPhoto.objects.all()
validation = CleanedDataFormValidation(form_class=forms.SpkPhotoForm)
...
def dehydrate_img(self, bundle):
return repr(bundle.obj.filename.name)
def deserialize(self, request, data, format=None):
if format is None:
format = request.META.get('CONTENT_TYPE','application/json')
if format == 'application/x-www-form-urlencoded':
return request.POST
elif format.startswith('multipart'):
data = request.POST.copy()
data.update(request.FILES)
return data
return super(SpkPhotoResource, self).deserialize(request, data, format)
//model:
class SpkPhoto(models.Model):
....
filename = models.ImageField(db_column='FILENAME', max_length=256, upload_to=getFilePath, null=False, blank=False)
site_order = models.SmallIntegerField(db_column='SITE_ORDER', blank=True, null=True)
class Meta:
...
def save(self, *args, **kwargs):
p = str('media/OFFICE/' + str(self.spk_propertyid.office.id))
self.filename.storage = FileSystemStorage(location = p )
if not self.spk_photoid:
self.spk_photoid = get12charid_spk_photoid()
super(SpkPhoto, self).save(*args, **kwargs)
def delete(self, *args, **kwargs):
p = str('media/OFFICE/' + str(self.spk_propertyid.office.id))
self.filename.storage = FileSystemStorage(location = p )
self.filename.delete()
super(SpkPhoto, self).delete(*args, **kwargs)

FormData multipart -Ajax-post- DJANGO-tastie-deserialize data in querydict is as array so just remake returned data from deserialize make it ok
def deserialize(self, request, data, format=None):
if format is None:
format = request.META.get('CONTENT_TYPE','application/json')
if format == 'application/x-www-form-urlencoded':
return request.POST
elif format.startswith('multipart'):
data = request.POST.copy()
data.update(request.FILES)
data2 = {}
for name, value in data.items():
data2[name] = value
return data2
return super(SpkPhotoResource, self).deserialize(request, data, format)

Related

Matching query doesn't exist?

I am making a retweet function and it works quite smooth but I am not able to retweet my own tweets , I am able to retweet other users tweets but not mine
. It shows that matching query doesn't exist.
Here is the tweets models
class TweetManager(models.Manager):
def retweet(self,user,parent_obj):
if parent_obj.parent:
obj_parent = parent_obj.parent
else:
obj_parent = parent_obj
qs = self.get_queryset().filter(user = user, parent = obj_parent)
if qs.exists():
return None
obj = self.model(
user = user,
parent = obj_parent,
content = parent_obj.content
)
obj.save()
return obj
class Tweet(models.Model):
parent = models.ForeignKey("self",blank = True,null = True)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
content = models.CharField(max_length = 130)
time = models.DateTimeField(auto_now_add = True)
objects = TweetManager()
def __str__(self):
return self.content
class Meta:
ordering = ['content']
Here's the views.py
class Retweet(View):
def get(self, request, pk, *args, **kwargs):
tweet = get_object_or_404(Tweet, pk=pk)
if request.user.is_authenticated:
new_tweet = Tweet.objects.retweet(request.user, tweet)
return HttpResponseRedirect("/")
return HttpResponseRedirect(tweet.get_absolute_url())

Uploaded Model Data WIth DRF Data Does Not Save

I'm trying to upload a photo along with other data for my CustomerDetails model via an api endpoint. The data seems to save but, when I check my table, there is no data present.
Here is my model:
class CustomerDetails(models.Model):
Sizes = (
('Sizes', (
('small', 'small'),
('medium', 'medium'),
('large', 'large'),
)),
)
CATEGORIES = (
('Usage', (
('Headache', 'Headache'),
('Backaches', 'Insomnia'),
('Menstrual Cramps & Pains','Menstrual Cramps
)),
)
CUSTYPE = (
('Customer Type',(
('Athlete', 'Athlete'),
('Non-Athlete', 'Non-Athlete'),
)),
)
age = models.IntegerField(default="21", blank=True)
nick_name = models.CharField(max_length=500, blank=True)
average_order = models.FloatField(default = "0.0", blank=True)
completed_orders = models.IntegerField(default = "0", blank=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='customer')
customer_type = MultiSelectField(choices=CUSTYPE, default = CUSTYPE, max_length=100)
current_selfie = models.ImageField(upload_to= 'sefies/', blank=True, default='')
favorite_color = MultiSelectField(choices=TYPE, max_length=100)
interested_in = MultiSelectField(choices=CATEGORIES, max_length=1000)
last_signin = models.DateTimeField(default = timezone.now)
liked_stores = models.ManyToManyField('Stores')
liked_products = models.ManyToManyField('Product')
phone = PhoneField(blank=True, help_text='Contact phone number')
shares = models.IntegerField(default = "0", blank=True)
signup = models.DateTimeField(default = timezone.now)
def __str__(self):
return self.customer.user.get_full_name()
Here are my serializers & Url
url(r'^api/customer/create_customer_details/$', apis.CustomerDetailViewset.as_view()),
class CustomerDetailUploader(serializers.ModelSerializer):
customer = CustomerDetailSerializer()
current_selfie = serializers.SerializerMethodField()
def get_current_selfie(self, store):
request = self.context.get('request')
current_selfie_url = CustomerDetails.current_selfie.url
return request.build_absolute_uri(current_selfie_url)
class Meta:
model = CustomerDetails
fields = ('nick_name', 'customer', 'current_selfie', 'favorite_color', 'interested_in', 'customer_type')
Here is the apiView I'm using:
class CustomerDetailViewset(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I'm trying to create a new customerDetails page for every user when they sign up, assign the data to a Customer, and save the details. Everytime I try to call the function, I do get the success message:
[15/Feb/2019 22:56:10] "POST /api/customer/create_customer_details/?access_token=U3EvAbo1HhOwNAgcEYUR4WOegul6ye HTTP/1.1" 201 99
Can anyone let me know how I can fix this?
You can try this save image (Base64) using DRF
serializer.py
class Base64ImageField(serializers.ImageField):
def to_internal_value(self, data):
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
self.fail('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = self.get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension, )
data = ContentFile(decoded_file, name=complete_file_name)
return super(Base64ImageField, self).to_internal_value(data)
def get_file_extension(self, file_name, decoded_file):
import imghdr
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
class CustomerDetailUploader(serializers.ModelSerializer):
customer = CustomerDetailSerializer()
current_selfie = Base64ImageField()
class Meta:
model = CustomerDetails
fields = ('nick_name', 'customer', 'current_selfie', 'favorite_color', 'interested_in', 'customer_type')
in api.py
class CustomerDetailViewset(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Reponse ({})
hope it help for your problem
Maybe you have some errors, but you are not seeing them, because you're return always 201. The first Response should be inner the if branch.
Your code:
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
correct code:
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Django queryset calling only objects belonging to User

I'm unable to figure out how to only call a queryset of items that belong to a specific User in the django forms.
dropoffs/models.py
class DropoffItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
dropoff = models.ForeignKey('Dropoff', null=True, blank=True)
product = models.ForeignKey(Product)
location = models.CharField(max_length=120, choices=LOCATION_CHOICES, default="Customer")
def __str__(self):
return str('%s' + " " + "(" + '%s' + ")") %(self.product.title, self.product.sku)
def sku(self):
return self.product.sku
def title(self):
return self.product.title
def dropoff_id(self):
return str(self.dropoff.id)
forms.py
class AddPickupItemForm(forms.ModelForm):
dropoffitem = forms.ModelChoiceField(queryset=DropoffItem.objects.none())
class Meta:
model = PickupItem
# fields = ["product", "quantity"]
fields = ['dropoffitem']
def __init__(self, user, *args, **kwargs):
# self.request = kwargs.pop("request")
the_user = kwargs.pop('user', None)
super(AddPickupItemForm, self).__init__(*args, **kwargs)
if the_user is not None:
self.fields["dropoffitem"].queryset = DropoffItem.objects.filter(user=the_user)
views.py
def add_item_to_pickup_order(request):
request.session.set_expiry(120000)
try:
user = request.user
the_id = request.session['pickup_id']
pickup = Pickup.objects.get(id=the_id)
except:
user = request.user
new_pickup_order = Pickup(user=user)
new_pickup_order.save()
request.session['pickup_id'] = new_pickup_order.id
the_id = new_pickup_order.id
pickup = Pickup.objects.get(id=the_id)
try:
dropoffitem = DropoffItem.objects.filter(user=user)
except DropoffItem.DoesNotExist:
pass
except:
pass
form = AddPickupItemForm(request.POST, user=request.user)
if request.method == "POST":
dropoffitem_id = int(request.POST['dropoffitem'])
pickup_item = PickupItem.objects.create(pickup=pickup, dropoffitem_id=dropoffitem_id)
pickup_item.save()
return HttpResponseRedirect('%s'%(reverse('add_item_to_pickup_order')))
context = {
"pickup": pickup,
"form": form,
}
return render(request, 'pickups/create_pickup_order.html', context)
With the modifications to init, I'm getting a TypeError of: init() got multiple values for keyword argument 'user'.
Could that be because of how I'm requesting a 'session'?
class AddPickupItemForm(ModelForm):
def __init__(self,*args,**kwargs)
the_user = kwargs.pop('user',None)
super(AddPickupItemForm, self).__init__(*args,**kwargs)
if the_user is not None:
self.fields['dropoffitem'].queryset = DropOffItem.objects.filter(user=the_user)
In other words, pass your user to the form when instantiating, if you need to.

Django form with filefield loses the file when editing an instance

I'm trying to make a form that can be used to make a new instance of "LearningObjects" as well as edit existing instances. It seems to work fine except that when I'm editing an existing instance I lose the filefield. Since it is a required field it asks me to upload a new file and obviously I don't always want to do that.
Form.py
class LearningObjectuploadform(forms.ModelForm, edit):
level = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple,queryset=None,required=False)
agebracket =forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple,queryset=None,required=False)
pathway = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple,queryset=None,required=False)
class Meta:
model = LearningObject
fields =['title','archivefile','description','tags','pathway','level','subject','agebracket']
def __init__(self, *args, **kwargs):
super(LearningObjectuploadform, self).__init__(*args, **kwargs)
self.fields['level'].queryset = AssoeLevel.objects.all()
self.fields['pathway'].queryset = AssoePathway.objects.all()
self.fields['agebracket'].queryset = AgeBracket.objects.all()
View.py
def createLearningobject(request,learningobject_pk=False):
if request.method == 'GET':
if learningobject_pk:
print learningobject_pk
instance = LearningObject.objects.get( pk=learningobject_pk)
print instance
form = LearningObjectuploadform(request.POST or None, request.FILES or None, instance=instance)
else:
form = LearningObjectuploadform()
else:
form = LearningObjectuploadform(request.POST, request.FILES)
if form.is_valid():
learningobject = request.FILES['archivefile']
title = form.cleaned_data['title']
description = form.cleaned_data['description']
tags = form.cleaned_data['tags']
levels = form.cleaned_data['level']
pathways = form.cleaned_data['pathway']
agebrackets = form.cleaned_data['agebracket']
post = LearningObject.objects.create(archivefile=learningobject,title=title, description=description)
for tag in tags:
post.tags.add(tag)
for level in levels:
post.level.add(level.pk)
for pathway in pathways:
post.pathway.add(pathway.pk)
for agebracket in agebrackets:
post.agebracket.add(agebracket.pk)
post.save()
return HttpResponseRedirect(reverse('index', ))
else:
print "form not valid"
return render(request, 'mediamanager/edit_learningobject.html', {'form': form,})
Models.py
class DefaultResource(models.Model):
#
# This class is the parent class for all resources in the media manager
#
title = models.CharField(max_length=100)
created_date = models.DateTimeField(auto_now_add=True, auto_now=False)
edited_date = models.DateTimeField(auto_now_add=False,auto_now=True)
level = models.ManyToManyField(AssoeLevel)
agebracket= models.ManyToManyField(AgeBracket)
pathway= models.ManyToManyField(AssoePathway)
tags = TaggableManager()
slug = models.SlugField(max_length=100,editable=False,blank=True)
updownvotes = RatingField(can_change_vote=True)
views = models.DecimalField(max_digits=20,decimal_places=2,default=0,blank=True)
score = models.DecimalField(max_digits=20,decimal_places=4,default=0,blank=True)
icon = models.CharField(max_length=254,editable=False,blank=True)
subject = models.ManyToManyField(AssoeSubjects)
#def return_tags(self):
# taglist = self.tags.names()
# return taglist
def calculate_score(self):
score = float(self.updownvotes.likes) - float(self.updownvotes.dislikes)
score = score + (float(self.views)**(float(1)/float(2)))
self.score = score
rounded_score = int(round(self.score))
if rounded_score < -1:
return -1
else:
return rounded_score
def __unicode__ (self):
return self.title
def save(self, *args, **kwargs):
self.calculate_score()
if not self.id:
self.slug = slugify(self.title)
super(DefaultResource, self).save(*args, **kwargs)
class LearningObject(DefaultResource):
archivefile = models.FileField(upload_to='static/learningobject/archivefiles/%Y/%m/%d')
indexpath = models.CharField(max_length=254,editable=False,blank=True)
description = models.TextField(blank=True)
def unpackarchive(self):
archive = self.archivefile
filename = os.path.basename(str(archive))
folder = str(filename).split(".")[0]
print folder
index_found = "False"
with zipfile.ZipFile(archive,"r") as z:
for each in z.namelist():
if each == "index.html" or each == "index.htm":
index_found = "True"
else:
pass
if not index_found:
print "zip file does not contain a valid index.html file"
else:
path = os.path.join("static","learningobject","unpackedarchives",folder)
z.extractall(path)
self.findindex(path)
def findindex(self,path):
print path
for root, dirnames, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, 'index.ht*'):
print filename
self.indexpath = os.path.join(root, filename)
print self.indexpath
def save(self, *args, **kwargs):
self.icon = "/static/images/icons/box.png"
self.unpackarchive()
super(LearningObject, self).save(*args, **kwargs)
I have faced similar problems with file uploads in django forms. This is what I hope should help you out(provided you are willing to alter the required attribute of the archivefile field.)
if request.method == 'GET':
if learningobject_pk:
print learningobject_pk
instance = LearningObject.objects.get( pk=learningobject_pk)
print instance
form = LearningObjectuploadform(request.POST or None, request.FILES or None, instance=instance)
form.base_fields['archivefile'].required = False
else:
form = LearningObjectuploadform()

Access missing value in form.cleaned_data

I was trying to dynamically generate fields as shown in http://jacobian.org/writing/dynamic-form-generation/. My case slightly differs in that I am looking to use multiplechoicefield that is dynamically created. This is what I came up with...
views.py
def browseget(request):
success = False
if request.method == 'POST':
list_form = ListForm(request.POST)
if list_form.is_valid():
success = True
path = list_form.cleaned_data['path']
minimum_size = list_form.cleaned_data['minimum_size']
follow_link = list_form.cleaned_data['follow_link']
checkboxes = list_form.cleaned_data['checkboxes']
....do something
else:
list_form = ListForm(name_list)
ctx = {'success': success, 'list_form': list_form, 'path': path, 'minimum_size': minimum_size}
return render_to_response('photoget/browseget.html', ctx, context_instance=RequestContext(request))
forms.py
class ListForm(forms.Form):
path = forms.CharField(required=False)
minimum_size = forms.ChoiceField(choices=size_choices)
follow_link = forms.BooleanField(required=False, initial=True)
def __init__(self, *args, **kwargs):
name_list = kwargs.pop('name_list', None)
super(ListForm, self).__init__(*args, **kwargs)
print 'Received data:', self.data
if name_list:
name_choices = [(u, u) for u in name_list]
self.fields['checkboxes'] = forms.MultipleChoiceField(required=False, label='Select Name(s):', widget=forms.CheckboxSelectMultiple(), choices=name_choices)
def clean_path(self):
cd = self.cleaned_data
path = cd.get('path')
if path == '': path = None
return path
def clean_minimum_size(self):
cd = self.cleaned_data
minimum_size = cd.get('minimum_size')
if minimum_size is None: minimum_size = 0
return int(minimum_size)
The form generates and displays perfectly... until I post some data. The 'checkboxes' field doesn't show up in list_form.cleaned_data.items() while it shows in self.data. As it is the form breaks with a KeyError exception. So Im asking, how do i access the checkboxes data?
You're not passing in the name_list parameter when you re-instantiate the form on POST, so the field is not created because if name_list is False.