I'm working on my first Django project (IDE: PyCharm, OS: Win10). There is a problem with .js. I renamed variable called 'nmb' to 'quantity' in the script. This variable was created for counting products in user's cart. Then I've got an error that ItemInCart model gets an 'undefined' quantity instead of some countable value. It happens because only on 8000 port jQuery still seeks for 'nmb' not for data attr name 'quantity'. Running my app on any other port, like 8023 everything works well.
JS
$ (document).ready(function () {
var form = $('#form_buy_item');
console.log(form);
form.on('submit', function (e) {
e.preventDefault();
var quantity = $('#quantity').val();
console.log(quantity);
var csrf_token;
var submit_btn = $('#submit_btn');
var item_id = submit_btn.data('item_id');
var item_name = submit_btn.data('item_name');
var item_price = submit_btn.data('item_price');
console.log(item_name, item_id);
var data = {};
data.item_id = item_id;
data.item_name = item_name;
data.quantity = quantity;
csrf_token = $('#form_buy_item [name = "csrfmiddlewaretoken"]').val();
data["csrfmiddlewaretoken"] = csrf_token;
// use action attribute for multi-language support
var url = form.attr("action");
console.log(data);
$.ajax({
url: url,
type: 'POST',
data: data,
cache: true,
success: [ function (data) {
console.log("OK");
console.log(data.items_total_count);
if (data.items_total_count){
$('#cart_total_quantity').text('data.items_total_count')
}
} ],
error: function() {
console.log("error")
}
});
$('.cart-items ul').append('<li>'+item_name +', ' + quantity + ' item(s), ' + item_price + '$ per item '+
'<a class="delete-item" href=""> x <a>' + '</li>')
});
function displayCartItems(){
$('.cart-items').toggleClass('hidden');
}
$('.cart-container').on('click, hover', function (e) {
e.preventDefault();
displayCartItems();
});
$('.cart-container').mouseover('click, hover', function (e) {
e.preventDefault();
displayCartItems();
});
$('.cart-container').mouseout('click, hover', function (e) {
e.preventDefault();
displayCartItems();
});
$(document).click('click', 'delete-item', function(e) {
e.preventDefault();
$(this).closest('li').removeAttr()
});
});
Model
class ItemInCart(models.Model):
session_key = models.CharField(max_length=128, null=True, blank=True, default=None)
order = models.ForeignKey(Order, on_delete=models.SET_DEFAULT, blank=True, null=True, default=None)
item = models.ForeignKey(Item, on_delete=models.SET_DEFAULT, blank=True, null=True, default=None)
quantity = models.IntegerField(default=1)
price_per_item = models.DecimalField(max_digits=10, decimal_places=2, default=0)
total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
class Meta:
verbose_name = 'Item in cart'
verbose_name_plural = 'Items in cart'
def save(self, *args, **kwargs):
price_per_item = self.item.price
self.price_per_item = price_per_item
self.total_price = int(self.quantity) * self.price_per_item
super(ItemInCart, self).save(*args, **kwargs)
Views
def cart_add(request):
return_dictionary = dict()
session_key = request.session.session_key
print(request.POST)
data = request.POST
item_id = data.get('item_id')
quantity = data.get('quantity')
# is_delete = data.get('is_delete')
new_item = ItemInCart.objects.create(session_key=session_key, item_id=item_id, quantity=quantity)
items_total_count = ItemInCart.objects.filter(session_key=session_key, is_active=True).count()
return_dictionary['items_total_count'] = items_total_count
print(request.POST)
return JsonResponse(return_dictionary)
This is happened on 8000, 8001
8024 is fine
Please clear browser history then run the application.
Related
Im using angular/typescript where I upload a form of data to my Django REST API. With the data all is correct, because I can log my whole form and I get back all my data. But when it comes to upload the data I get this error:
{src: ["No file was submitted."], tag: ["This field is required."]}
so somehow it does not recognize my data because Im actually submitting data.
frontend code
upload.service
const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'multipart/form-data'})
};
...
uploadPost(src: File, tag: string) {
return this.http.post<any>(`{this.url}/posts/`, {src, tag}, httpOptions);
}
post.page
ngOnInit() {
this.storage.get('image_data').then((imageFile) => {
console.log(imageFile)
this.categoryForm.patchValue({
'image': this.storage.get('image_data')
});
});
this.categoryForm = new FormGroup({
'category': new FormControl('', Validators.compose([
Validators.maxLength(25),
Validators.minLength(1),
Validators.required
])),
'image': new FormControl(null),
});
apiSubmit() {
console.log('logged')
console.log(this.f.image);
this.submitted = true;
if (this.categoryForm.invalid) {
return;
}
this.isLoading = true;
this.loadingEl.present();
this.uploadService.uploadPost(
this.f.image,
this.f.category
)
.pipe(tap(x => this.loadingEl.dismiss())
)
.subscribe(
data => {
this.router.navigate(['one']);
},
error => {
this.error = error;
}
);
}
Django:
models.py
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='posts', on_delete=models.CASCADE)
src = models.ImageField(blank=False, null=False, editable=False, upload_to=utils.get_file_path,)
date_posted = models.DateTimeField(auto_now_add=True, editable=False)
last_modified = models.DateTimeField(auto_now=True)
when = models.FloatField(blank=True, null=True)
lock = models.BooleanField(default=False)
des = models.CharField(
max_length=100,
validators=[
RegexValidator(
regex='^[-_a-zA-Z0-9\.]+$',
message='only 1 to 20 characters and only letters, numbers, point, minus and underscore are allowed',
),
])
view.py
#swagger_auto_schema(request_body=doc_serializer.CreatePostDummy, responses={201: PostSerializer})
def create(self, request, *args, **kwargs):
"""permission required: authenticated. Note: the schema is not json it's multipart"""
return super().create(request, *args, **kwargs)
doc_serializers.py
class CreatePostDummy(serializers.HyperlinkedModelSerializer):
`enter code here`user = serializers.HyperlinkedRelatedField(required=False, read_only=True, view_name='user-detail')
src = serializers.CharField(required=True, help_text='Not Char but image upload field')
I am getting NOT NULL constraint error even after passing the data from the form. I am using ajax for posting the data. I checked both the request.POST and network request tab. Both shows the store_contact_number has data in it.
Here is my code
class ListStore(FormView):
form_class = StoreForm
template_name = 'Store/list-store.html'
def form_invalid(self, form):
if self.request.is_ajax():
print('ajax form error', form.errors)
response = {
'error': form.errors
}
return JsonResponse(response, status=400)
else:
return super(ListStore, self).form_invalid(form.errors)
def form_valid(self, form):
success_message = "Thank you for listing your store. We Welcome you."
store, created = Store.objects.get_or_create(merchant=self.request.user)
if self.request.is_ajax():
response = {
'result': success_message
}
return JsonResponse(response)
else:
message.success(self.request, success_message)
return self.render_to_response(self.get_context_data())
class Store(models.Model):
merchant = models.ForeignKey(User, blank=False, null=False)
token = models.CharField(default=token_generator, max_length=20, unique=True, editable=False)
name_of_legal_entity = models.CharField(max_length=250, blank=False, null=False)
pan_number = models.CharField(max_length=20, blank=False, null=False)
registered_office_address = models.CharField(max_length=200)
name_of_store = models.CharField(max_length=100)
email = models.EmailField(blank=False, null=False)
store_contact_number = models.PositiveIntegerField(blank=False, null=False)
$('.list-store-form').on('submit', function(event) {
event.preventDefault(); // preventing from the brwoser default behavior for form submission
var form = $(this);
console.log(form);
$.ajax({
async: true,
url: form.attr('action'),
data: form.serialize(),
type: 'POST',
dataType: 'json',
headers: {
'X-CSRFToken': window.csrf_token
},
success: function(data) {
if (data.form_is_valid) {
alert('Store Listed');
}
// $('.display').html(
// "<div class='ui floating message'> <i class='close icon'></i>" + data.result + '</div>'
// );
},
The error is shown in the store_contact_number as
IntegrityError at /list/store NOT NULL constraint failed:
Store_store.store_contact_number
<QueryDict: {'store_contact_number': ['98489678'], 'email': ['admin#gmail.com'], 'registered_office_address': ['Delhi'], 'csrfmiddlewaretoken': ['kSaPMgNt'], 'name_of_store': ['BigMart'], 'pan_number': ['98713962'], 'name_of_legal_entity': ['BigMart Pvt Ltd']}>
Form
class StoreForm(forms.ModelForm):
class Meta:
model = Store
exclude = ('is_active', 'token', 'merchant',)
You need to add store = form.save() at the start of your form_valid method and get rid of the line store, created = Store.objects.get_or_create(merchant=self.request.user).
EDIT: Actually it's not that simple because the form.save() will also fail due to not having the merchant field specified. You'll need to either need to override either the __init__ or save method of your form so you can pass in the merchant.
Something like:
def save(self, merchant, *args, **kwargs):
commit = kwargs.pop('commit', True)
kwargs['commit'] = False
store = super().save(*args, **kwargs)
store.merchant = merchant
if commit:
store.save()
return store
then call it using:
def form_valid(self, form):
store = form.save(merchant=self.request.user)
success_message = "Thank you for listing your store. We Welcome you."
if self.request.is_ajax():
response = {
'result': success_message
}
return JsonResponse(response)
else:
message.success(self.request, success_message)
return self.render_to_response(self.get_context_data())
my view:
#csrf_exempt
def get_order_detail(request):
order_id = request.GET['order_id']
products_of_order = OrdersProducts.objects.filter(order=order_id).values('product__title', 'cargo_no', 'order',
'units', "status").values_list()
data = serializers.serialize("json", products_of_order)
return HttpResponse(data, content_type="text/json", safe=False)
my model:
class OrdersProducts(models.Model):
STATUS_CHOICES = (
(u'0', _(u'cancel')),
(u'1', _(u'waiting_for_payment')),
(u'2', _(u'waiting_for_cargo')),
(u'3', _(u'on_the_road')),
(u'4', _(u'success_shipping')),
(u'5', _(u'failure_shipping')),
(u'6', _(u'return'))
)
units = models.PositiveSmallIntegerField(default=1, null=False, blank=False)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='1')
cargo_no = models.CharField(max_length=11, default='', null=True, blank=False)
product = models.ForeignKey(Products)
order = models.ForeignKey(Orders)
optional_price = models.ForeignKey(OptionalPrice, default=1)
company_optional_price = models.ForeignKey(CompanyOptionalPrice, default=1)
cdate = models.DateTimeField(auto_now_add=True)
my template:
$('.order-btn').click(function(event) {
var order = $(this).data('id');
var items = [];
$('#table_order').find('tbody').empty();
if ( order != "" ) {
items.push ('');
$.getJSON ( '{% url 'get_order_detail' %}', {order_id:order}, function(data) {
console.log('sa');
$.each ( data, function ( index, val ) {
console.log(data);
items.push ( '<tr><td>' + val.fields.order + '</td> <td>' + val.fields.product_name + '</td> <td>' + val.fields.units + '</td> <td>' + val.fields.optional_price + '</td> <td>' + val.fields.get_status_display + '</td> <td>' + val.fields.cargo_no + '</td></tr>');
console.log(items)
} );
$('#table_order').find('tbody').append( items );
} );
}
});
error:
tuple' object has no attribute '_meta'
I need a values('product__title', 'cargo_no', 'order', 'units', "status"). If I can my mymodel.objects.all(), don't use product.name values,etc.
Note: My template page is old values when I use to direct my model.
I want to return only the clandpin fields. I have this model below:
model.py
class ButuanMaps(gismodel.Model):
class Meta:
verbose_name = u'Butuan Map'
verbose_name_plural = u'Butuan Maps'
clandpin = gismodel.CharField("Land PIN", max_length=50, null=True, blank=True)
ssectionid = gismodel.ForeignKey(Section)
#ssectionid_id = gismodel.IntegerField()
geom = gismodel.MultiPolygonField("Geom ID", srid=32651, null=True, blank=True)
objects = gismodel.GeoManager()
def __unicode__(self):
return self.clandpin
In my template, here's the code for AJAX:
<script type="text/javascript">
$(document).ready(function() {
$("#formsection").change(function() {
$.ajax({
url : "/sectionpins",
type : "GET",
dataType: "html",
data : {
'sectionid' : $('#formsection').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success : searchSuccess,
error: errs
});
return false;
});
});
function searchSuccess(data){
alert("Success");
$('#forminput').append(
"<option value='"+data+"'>"+data+"</option>"
);
}
function errs(){
alert('Error!!!!');
}
</script>
In views.py:
def section_landpins(request):
if request.method == "GET":
m = ButuanMaps.objects.filter(ssectionid=request.GET['sectionid'])
landpins = serializers.serialize("json", m.values('clandpin'), fields=("clandpin"))
data = json.dumps({
'pins': landpins,
})
return HttpResponse(data, content_type='application/json')
It returned an error
AttributeError at /sectionpins'dict' object has no attribute '_meta'
When I changed the query with this:
m = ButuanMaps.objects.filter(ssectionid=request.GET['sectionid'])
It doesn't return an error but this:
{"pins": "[{\"pk\": 185625, \"model\": \"tbl.butuanmaps\", \"fields\": {\"clandpin\": \"162-12-0001-055-37\"}}
You can do this by requesting only the field you are interested in from the ORM, then evaluating the ValueQuerySet into a list of dictionaries:
section_id = request.GET.get('sectionid', 'defaultid')
m = ButuanMaps.objects.filter(ssectionid=section_id).values('landpins')
return HttpResponse(json.dumps({'pins': list(m)}),
content_type='application/json')
I send data from html fields via AJAX
var dataToSend = { some1 : $('.name1').html().replace(/[\n\r]/g, '').trim(),
some2 : $('.name2').html().replace(/[\n\r]/g, '').trim(),
some3 : $('.name3').html().replace(/[\n\r]/g, '').trim(),
some4 : $('.name4').html().replace(/[\n\r]/g, '').trim() }
if (dataToSend) {
$.ajax({
url: 'do/smth',
data: dataToSend,
async: false,
type: 'POST',
success: function() {
alert('draft is saved')
}
});
}
Then i receive POST request which does contain data but my model saves only when all arguments are existing, so for example if i get only {some1:"value1",some2:"value2"} my django view WONT save it.
The question is: how can i possibly save data into db, if my fields are empty, as you can see i have blank=True in my model, but it does not help
model
class Draft(models.Model):
name = models.CharField(_('company name'), max_length=100, blank=True)
slug = models.SlugField(max_length=255, blank=True)
pitch = models.CharField(_('pitch'), max_length=140, blank=True)
url = models.CharField(_('url'), max_length=255, null=True, blank=True)
thesis = models.TextField(_('thesis'), blank=True)
def __unicode__(self):
return self.name
views
def save_from_ajax_post(request):
data = dict(request.POST.items())
draft = Draft.objects.create(data)
draft.save()
return HttpResponse(json.dumps({'status': 1}), content_type="application/json")