My module
class module(models.Model):
name = models.CharField(max_length=255)
package = models.ForeignKey(package,on_delete=models.CASCADE,null = True)
class package(models.Model):
package_name = models.TextField(null=True,blank=True)
views.py
def list_modules(request):
paginator = PageNumberPagination()
paginator.page_size = 20
package=package.objects.filter(id=request.data['package']).order_by('id')
module =module.objects.filter(active_flag = True,package_id=request.data['package'])
paginate = paginator.paginate_queryset(module, request)
serializer = ModulesSerializer(paginate, many=True)
print(serializer.data)
data = paginator.get_paginated_response(serializer.data)
return data
Serializer.py
class ModulesSerializer(serializers.ModelSerializer):
class Meta:
model=module
fields=('id','name')
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = package
fields=('id','name')
Vuetify
Module(type,id){
var data={"package":id}
var url = this.page ? '/projects/list_modules?page='+this.page : '/home'
this.$axios.$post(url,data,config).then(response => {
if(response){
this.modules = response.results
}
}).catch(e => {
})
},
getPackages(){
var data={"portfolio":this.filter_portfolio}
var url = this.page ? '/projects/list_packages?page='+this.page : '/home'
this.$axios.$post(url,data,config).then(response => {
if(response){
this.packages = response.results
}
}).catch(e => {
})
},
i am showing response from getPackages()like this in data table
<v-data-table
<template v-slot:items="props">
<td>{{ props.item.name }}</td>
I want to show Module() data in same datatable
Can I append two api's response date into single data?
Related
I want to create Aviz entry using AJAX form.
In the form the input material has a jquery ui function autocomplete, that gets all the material names from the Material Model.
When I submit the form I get this error in the console : ValueError: Cannot assign "'ADEZIV LIPIRE VATA MINERALA, CT 180, 25 KG CERESIT'": "Aviz.material" must be a "Material" instance.
I know that I need to get the input from the form, and turn it in a Material instance...but do not know how/did not find any info about this.
models.py:
class Material(models.Model):
name = models.CharField(max_length=255,default=None,verbose_name='Nume material')
class Aviz(models.Model):
material = models.ForeignKey(Material, on_delete=models.CASCADE,related_name="aviz")
quantity = models.FloatField(default=0,verbose_name="Cantitate")
views.py:
class AvizCreate(LoginRequiredMixin, AjaxCreateView):
model = Aviz
form_class = AvizForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['pk'] = self.kwargs.get('centrudecost')
return kwargs
#login_required
def autocomplete(request):
if 'term' in request.GET:
qs = Material.objects.filter(name__icontains=request.GET.get('term'))
name = list()
id = list()
cod_nexus = list()
name = [prod.name for prod in qs]
id = [prod.pk for prod in qs]
cod_nexus = [prod.cod_nexus for prod in qs]
return JsonResponse({"name": name, "id":id, "cod_nexus":cod_nexus}, safe=False)
templates.html
$('#id_material').autocomplete({
source: function(request, response) {
$.ajax({
url: "{% url 'materiale:autocomplete' %}",
dataType: "json",
data: {
term: request.term
},
success: function(data) {
response($.map(data.name, function(value, key) {
return {
label: data.name[key],
value: data.name[key],
id:data.id[key],
cod_nexus:data.cod_nexus[key]
}
}));
}
});
},
select: async function(event, ui) {
let resp = await fetch("{% url 'materiale:get_um' 1 %}".replace('1',ui.item.id));
let json = await resp.json()
$('#id_um').val(json);
}
})
}
forms.py:
class AvizForm(BootstrapHelperForm, forms.ModelForm):
material = forms.CharField()
um = forms.CharField()
class Meta:
model = Aviz
fields = ('centrudecost','data','aviz', 'material','um','quantity',)
widgets = {
'data': DateInput(),
'centrudecost': forms.HiddenInput(),
# 'material': forms.Select(attrs={'class': 'form-control'})
}
def __init__(self, *args, **kwargs):
pk = kwargs.pop('pk', None)
super(AvizForm, self).__init__(*args, **kwargs)
self.fields['um'].widget.attrs['readonly'] = True
I know that by deleting this material = forms.CharField() from the forms.py, the form works, and a Aviz instance is created referencing the material model, but i need to use the autocomplete function in the form
I am trying to pass a list of student IDs but it is not working.
from angular I am passing data as follows
let noticeData = this.announceForm.value;
if (noticeData.students.includes('all')){
noticeData.students = noticeData.students.filter((s) => s != 'all')
}
noticeData.students = JSON.stringify(noticeData.students);
rest call
var formData = new FormData();
for (var key in noticeData) {
formData.set(key, noticeData[key]);
}
this._rest.one("/classwork/notices/")
.post('', formData)
.toPromise()
.then((classworks) => {
}, (error) => {
console.log("ERROR SENDING ANNOUNCEMENT ", error);
this.alert = {
type : "error",
message: "Something went wrong, please try again."
}
});
}
from django i am reading and trying to store data as
Below is the to_internal_value method which I have overridden.
def to_internal_value(self, data):
tempdict = data.copy()
tempdict['students'] = json.loads(data['students'])
data = tempdict
return super(NoticesSerializer, self).to_internal_value(data)
views.py
class ClassworkView(APIView):
def get(self, request, format=None):
notices = ClassworksFilter(request.query_params, queryset=Notice.objects.all()).qs
materials = ClassworksFilter(request.query_params, queryset=Material.objects.all()).qs
assignments = ClassworksFilter(request.query_params, queryset=Assignment.objects.all()).qs
queryset = sorted(
chain(notices, materials, assignments),
key=lambda instance: instance.create_date
)
model_serializers = {
'notice': NoticesSerializer,
}
classworks = []
for instance in queryset:
serializer = model_serializers[instance._meta.model_name]
data = serializer(instance).data
data['classwork_type'] = instance._meta.model_name
classworks.append(data)
page_number = request.query_params.get('page', 1)
page_size = request.query_params.get('page_size', 20)
page = Paginator(classworks, per_page=page_size).get_page(page_number)
base_url = f'{request.scheme}://{request.get_host()}{reverse("classworks")}'
params = [f'{k}={v}' if k!='page' else None for k,v in request.query_params.items()]
indx = 0
for param in params:
if param==None:
params.pop(indx)
indx+=1
params = '&'.join(params)
next = f'{base_url}?page={page.next_page_number()}&{params}' if page.has_next() else None
prev = f'{base_url}?page={page.previous_page_number()}&{params}' if page.has_previous() else None
response = {
'count': len(classworks),
'next': next,
'previous': prev,
'results': page.object_list
}
return Response(response)
here is serializer.py
class NoticesSerializer(serializers.ModelSerializer):
class Meta:
model = Notice
fields = '__all__'
def to_representation(self, instance):
representation = super(NoticesSerializer, self).to_representation(instance)
try:
representation['classroom'] = ClassroomsSerializer(instance.classroom, context=self.context).data
students = StudentsSerializer(instance.students, many=True, context=self.context).data
for student in students:
student['classroom'] = student['classroom']['id']
representation['students'] = students
except Exception as error:
print("ERROR SETTING REPRESENTATION FOR NOTICE SERIALIZER", error)
return representation
here is the models.py
class Notice(Classwork):
file = models.FileField(upload_to='classworks/attachments', blank=True, null=True)
link = models.URLField(blank=True, null=True)
description = models.TextField()
class Meta(BaseModel.Meta):
db_table = 'ec_notice'
but it always returns the same error
{students: [“Incorrect type. Expected pk value, received list.”]}
here the data I am posting by form data
When I try to send data via the frontend to the serializer I get a HTTP 400 error. If I do it directly via the DRF browsable API it works though:
model:
class Shipment(models.Model):
name = models.CharField("name", max_length = 128)
date = models.DateField()
class Product(models.Model):
serial = models.CharField("serial", max_length = 31, unique = True)
shipment = models.ForeignKey(Shipment, on_delete = models.CASCADE, blank = True, null = True)
serializer:
class ShipmentSerializer(serializers.ModelSerializer):
class Meta:
model = Shipment
fields = ["id", "name",]
class ProductSerializer(serializers.ModelSerializer):
shipment = ShipmentSerializer()
def update(self, instance, request):
product = Product.objects.get(serial = instance)
product.shipment = Shipment.objects.get(id = request["shipment"]["id"])
product.save()
return instance
class Meta:
model = Product
fields = ["serial", "shipment",]
lookup_field = "serial"
read_only_fields = ["serial",]
ViewSet:
class ProductViewSet(ModelViewSet):
serializer_class = ProductSerializer
lookup_field = "serial"
http_method_names = ["get", "patch", "put"]
def get_queryset(self):
return Product.objects.all()
AJAX call:
$.ajax({url: `api/products/${serial}/`,
dataType: "json",
contentType: "application/json",
type: "PUT",
data: {"shipment": shipment[0]},
headers: {"X-CSRFTOKEN": csrf_token },
success: function () {window.location = "?msg=ok";},
error: function () {window.location = "?msg=error";}
});
Browser output:
PUT
http://127.0.0.1:8000/api/products/d39f281f/
Status400
Bad Request
VersionHTTP/1.1
Transferred400 B (111 B size)
Referrer Policysame-origin
Request payload:
shipment=4
Response:
{"shipment":["This field is required."]}
or after some playing:
JSON parse error - Expecting value: line 1 column 1 (char 0)
why is the response field is required when there is a payload.
One way to approach this problem is to define two fields for shipment, one for writing and one for reading:
class ProductSerializer(serializers.ModelSerializer):
shipment_id = serializers.PrimaryKeyRelatedField(queryset=Shipment.objects.all(), write_only=True)
shipment = ShipmentSerializer(read_only=True)
class Meta:
model = Product
fields = ["serial", "shipment", "shipment_id"]
When you are updating, you can specify the id of the shipment using shipment_id:
{
"shipment_id": 10,
}
When you are retrieving or listing, the shipment details will come under shipment:
{
"serial": "",
"shipment": {
... # shipment details
}
}
I can't seem to upload an image to my project.
I always get this error when I try to submit the form from the frontend :
["The submitted data was not a file. Check the encoding type on the form."]
I've found some answers regarding the base64 encoding of the image but I can't seem to get it to work.
Any help would be much appreciated!!
thanks
here is the source code:
Models:
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField(default=0)
dob = models.CharField(max_length=10)
image = models.ImageField(upload_to='images/', null=True)
def __str__(self):
return self.name
class Details(models.Model):
party = models.ForeignKey(Person,on_delete=models.CASCADE,
related_name='party_details',null=True,blank=True)
adress = models.CharField(max_length=50)
date = models.CharField(max_length=20)
arrival= models.CharField(max_length=20)
def __str__(self):
return self.adress
Serializers:
class DetailsSerializer(serializers.ModelSerializer):
class Meta:
model = Details
# fields='__all__'
fields = ('id','party','adress','date','arrival')
class PersonSerializer(serializers.ModelSerializer):
party_details =DetailsSerializer(many=True)
class Meta:
model = Person
# fields='__all__'
fields = ('id','name','age','dob','image','party_details')
def create(self, validated_data):
named_details = validated_data.pop('party_details')
details = Person.objects.create(**validated_data)
for named_detail in named_details:
Details.objects.create(party=details, ** named_detail)
return details
def update(self,instance, validated_data):
named_details = validated_data.pop('party_details')
details = (instance.party_details).all()
details = list(details)
instance.name = validated_data.get('name', instance.name)
instance.age = validated_data.get('age', instance.age)
instance.dob = validated_data.get('dob', instance.dob)
instance.image = validated_data.get('image', instance.image)
instance.save()
for named_detail in named_details:
detail = details.pop(0)
detail.adress = named_detail.get('adress',detail.adress)
detail.date = named_detail.get('date',detail.date)
detail.arrival = named_detail.get('arrival', detail.arrival)
detail.save()
return instance
views:
class ListAllPerson (generics.ListCreateAPIView):
queryset=Person.objects.all()
serializer_class = PersonSerializer
class ListPerson (generics.RetrieveUpdateDestroyAPIView):
serializer_class = PersonSerializer
queryset= Person.objects.all()
class ListAllDetails(generics.ListCreateAPIView):
queryset=Details.objects.all()
serializer_class = DetailsSerializer
class ListDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = DetailsSerializer
queryset=Details.objects.all()
class CreateDetail(generics.ListCreateAPIView):
queryset=Details.objects.all()
serializer_class = DetailsSerializer
HTML FORM and Axios:
const profileImage = async ()=>{
let formField = new FormData()
formField.append('image',addImages)
await axios({
method: 'patch',
url: url,
data: formField
}).then((response) => {
history.push('/')
}).catch((error) => {
console.log(error);
})
}
<div className="add-image-input">
<form action="" className="add-image-form">
<input className="image-input" value={addImages}
onChange={(e)=>{setAddImages(e.target.value)}} type="file"/>
<button className="" type="button" onClick={profileImage} >add</button>
</form>
</div>
Hopefully you are using React js, this should help. At the point of
saving and submitting your form data, your function should look like this:
const onSubmit = (data) => {
console.log(data)
let form_data = new FormData();
form_data.append('upload_image_photo', data.cover_image, data.cover_image.name);
form_data.append('title', data.title);
form_data.append('category', data.category);
form_data.append('price_per_night', data.price_per_night);
form_data.append('room_slug', data.room_slug);
form_data.append('capacity', data.capacity);
form_data.append('room_size', data.room_size);
let url = '/url to the end point you are saving with the expected image field / ';
const config = {
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
};
axios.post(url, form_data, config)
.then(res => {
console.log(res.request.status);
console.log(res.data);
})
.catch(err => console.log(err))
};
in my project, user after register can complete his information in another form. after completed this form and submitted it every time he visits this page, he sees the completed form. but i have a problem in this form, calender of user's birthday field works well at the first time when field is empty, but after the form is completed and submitting when the user wants to change it the calendar looks like this:
models.py:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
ED_CHOICES = [
('hs', 'High school'),
('bc', 'Bachelor'),
('ms', 'Master'),
('do', 'Doctor'),
]
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=13)
birthday = models.DateField()
education = models.CharField(max_length=20, choices=ED_CHOICES)
gender = models.CharField(max_length=15)
forms.py:
class ProfileForm(forms.ModelForm):
ED_CHOICES = [
('hs', 'High school'),
('bc', 'Bachelor'),
('ms', 'Master'),
('do', 'Doctor'),
]
phone = forms.CharField(
widget=forms.TextInput(attrs={'class': 'input--style-4'}),
label=''
)
birthday = forms.DateField(
widget=forms.DateInput(attrs={'class': 'input--style-4 js-datepicker'}),
label=''
)
education = forms.CharField(
widget=forms.Select(choices=ED_CHOICES, attrs={'class': 'select-dropdown'}),
label=''
)
gender = forms.CharField(
widget=forms.TextInput(attrs={'class': 'radio-container m-r-45'}),
label=''
)
class Meta:
model = models.UserProfile
fields = ['phone', 'birthday', 'education', 'gender']
views.py:
from django.shortcuts import render, redirect
from . import forms, models
from django.contrib.auth import get_user_model
my_user = get_user_model()
my_profile = models.UserProfile
first = True
def profile(request, slug):
global first
user = my_user.objects.get(username=slug)
if first:
pro_form = forms.ProfileForm(request.POST or None)
else:
pro = my_profile.objects.get(user=user)
pro_form = forms.ProfileForm(request.POST or None, instance=pro)
form = forms.UserProfile(request.POST or None, instance=user)
context = {'FORM': form, 'PRO': pro_form, 'USER': user}
if form.is_valid() and pro_form.is_valid():
form.save()
pro = pro_form.save(commit=False)
pro.user = user
pro.save()
first = False
if 'gender' in request.POST:
pro_form.gender = request.POST.get('gender')
return redirect('HOME')
return render(request, 'accounts/index.html', context)
template:
<div class="row row-space">
<div class="col-2">
<div class="input-group">
<label class="label">Birthday</label>
<div class="input-group-icon">
{{ PRO.birthday }}
<i class="zmdi zmdi-calendar-note input-icon js-btn-calendar"></i>
</div>
</div>
</div>
js:
(function ($) {
'use strict';
/*==================================================================
[ Daterangepicker ]*/
try {
$('.js-datepicker').daterangepicker({
"singleDatePicker": true,
"showDropdowns": true,
"autoUpdateInput": false,
locale: {
format: 'DD/MM/YYYY'
},
});
var myCalendar = $('.js-datepicker');
var isClick = 0;
$(window).on('click',function(){
isClick = 0;
});
$(myCalendar).on('apply.daterangepicker',function(ev, picker){
isClick = 0;
$(this).val(picker.startDate.format('DD/MM/YYYY'));
});
$('.js-btn-calendar').on('click',function(e){
e.stopPropagation();
if(isClick === 1) isClick = 0;
else if(isClick === 0) isClick = 1;
if (isClick === 1) {
myCalendar.focus();
}
});
$(myCalendar).on('click',function(e){
e.stopPropagation();
isClick = 1;
});
$('.daterangepicker').on('click',function(e){
e.stopPropagation();
});
} catch(er) {console.log(er);}
/*[ Select 2 Config ]
===========================================================*/
try {
var selectSimple = $('.js-select-simple');
selectSimple.each(function () {
var that = $(this);
var selectBox = that.find('select');
var selectDropdown = that.find('.select-dropdown');
selectBox.select2({
dropdownParent: selectDropdown
});
});
} catch (err) {
console.log(err);
}
})(jQuery);