Add user to model before saving with DjangoModelFormMutation - django-forms

I have a Django Log model which has many-to-one with a User
from django.db import models
class Log(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
...
I have a Django form for the Log
from django.forms import ModelForm
class LogForm(ModelForm):
class Meta:
model = Log
exclude = ("user",)
I have a graphene-django mutation to enable Log creation
import graphene
from graphene_django import DjangoObjectType
from graphene_django.forms.mutation import DjangoModelFormMutation
class LogType(DjangoObjectType):
class Meta:
model = Log
fields = "__all__"
class CreateLogMutation(DjangoModelFormMutation):
log = graphene.Field(LogType)
class Meta:
form_class = LogForm
How do I set Log.user to the current user before saving? With Django class-based views you would do as follows:
from django.views.generic import CreateView
class LogCreateView(CreateView):
model = Log
form_class = LogForm
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
How is this achieved with graphene-django?

Override perform_mutate and add the user there. pefrom_mutate is called after Django's Form.is_valid.
class CreateLogMutation(DjangoModelFormMutation):
log = graphene.Field(LogType)
class Meta:
form_class = LogForm
#classmethod
def perform_mutate(cls, form, info):
form.instance.user = info.context.user
return super().perform_mutate(form, info)

Related

How to store enum data as Array List in a database using Kotlin

I have an enum class that contain multiple data ,I want to store that
enum data as list in database. for example Developer table it contain
technology column ,that column store enum data, Suppose one user want
to store Developer1 working on many technologies like java , Kotllin ,
.Net etc these technologies are belongs from enum class , How to store
.
Same as I have a Subject enum class that contain multiple subject name
,When I Register a new teacher then I want to store how many subjects
teacher know ,If he know multiple subjects that present in our enum
class list then store the subjects id which known by the teacher.But I
am not able to store multiple data in a single column in subjectId ,It
store only one Data in SubjectId column,If I pass multiple data in
subjectId column in postman it throws error 400
teacherEntity class
package com.nilmani.jpqlprojectexample.entity
import com.nilmani.jpqlprojectexample.enum.Subject
import com.nilmani.jpqlprojectexample.enum.University
import java.util.*
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class Teacher(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int = Subject.MATH.type,//List<Int> = listOf(Subject.MATH.type)
val university:Int=University.OTHER.type
)
Subject enum class
package com.nilmani.jpqlprojectexample.enum
enum class Subject(val type:Int) {
MATH(1),
PHYSIC(2),
ACCOUNTING(3),
ZOOLOGY(4),
BIOLOGY(5),
PROGRAMMING(6),
STATICS(7),
CHEMISTRY(8),
HISTORY(9)
}
ReqTeacher Model class
package com.nilmani.jpqlprojectexample.model.request
import com.nilmani.jpqlprojectexample.enum.Subject import com.nilmani.jpqlprojectexample.enum.University
data class ReqTeacher(
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int= Subject.MATH.type,
val university:Int= University.OTHER.type, )
Response Teacher Model class
package com.nilmani.jpqlprojectexample.model.response
import com.nilmani.jpqlprojectexample.enum.Subject
import com.nilmani.jpqlprojectexample.enum.University
data class ResTeacher(
val nameOfTeacher:String="",
val price:Long=-1,
val subject:Int= Subject.MATH.type,
val university:Int= University.OTHER.type,
)
Teacher controller class
package com.nilmani.jpqlprojectexample.controller
import com.nilmani.jpqlprojectexample.entity.Teacher
import com.nilmani.jpqlprojectexample.model.request.ReqTeacher
import com.nilmani.jpqlprojectexample.model.response.ResTeacher
import com.nilmani.jpqlprojectexample.repository.TeacherRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
#RestController
#RequestMapping("/teachTest")
class TeacherController {
#Autowired
private lateinit var teachRopo:TeacherRepository
#PostMapping("/add")
fun addTeacher(#ModelAttribute request:ReqTeacher):ResponseEntity<*>{
// val newTeacher = teachRopo.findById(request.)
var newTeacher = Teacher(
nameOfTeacher = request.nameOfTeacher,
price = request.price,
subject = request.subject,
university = request.university,
)
val saveTeacher = teachRopo.save(newTeacher)
val respTeacher = ResTeacher(
saveTeacher.nameOfTeacher,
saveTeacher.price,
saveTeacher.subject,
saveTeacher.university
)
return ResponseEntity(respTeacher,HttpStatus.OK)
}
}
I want to store multiple data or single data in SubjectId column of a
particular teacherId,But My code store only one data for a particular
teacherId
You should have a new table (Entity) that represents the 1-to-many relationship between Teacher and Subject, e.g. teacher_subject. This is the proper approach. If you attempt to store the subjects as space/comma-separated values in a single cell, e.g. "math, physics, biology" that would be bad practice.

How to handle this Type MisMatch found List required Entity spring Boot JPA

I create a some operations in my controller class ,I want to store
the results what i get from the operation but when I store these list
of things it show me an error like Below
Type mismatch.
Required:
DepositMaterial!
Found:
List<Result>
Here is my controller class
#PatchMapping("/pendingValue")
fun pend(#ModelAttribute request:ReqFindPending):ResponseEntity<*>{
val existingWithdraw = depositRepository.findPendingByWithDrawId(request.withDrawId)
if (existingWithdraw != null){
val upPending = depositRepository.getPending(withDrawId = request.withDrawId)
depositRepository.save(upPending)
return ResponseEntity(ResMessage("Pending update successfull"),HttpStatus.OK)
}else{
return ResponseEntity(ResMessage(" id getting null value"),HttpStatus.NOT_ACCEPTABLE)
}
}
My repository
package com.nilmani.workload.repository
import com.nilmani.workload.entity.DepositMaterial
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.RequestParam
interface DepositRepository : JpaRepository<DepositMaterial, Long> {
#Query("SELECT wm.quantity ,dd.totalDeposit,wm.quantity -dd.totalDeposit AS pending FROM WithdrawMaterial wm INNER JOIN DepositMaterial dd ON wm.id = dd.withDrawId ")
fun getPending(#Param("withDrawId")withDrawId: Long?):List<Result>
}
Here is my result Model
data class Result(
val pending: Long,
val quantity: Long,
val totalDeposit: Long
)
DepositMaterial Entity Class
package com.nilmani.workload.entity
import com.nilmani.workload.enum.Material
import java.time.LocalDateTime
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
#Entity
data class DepositMaterial (
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id:Long=-1,
val withDrawId:Long=-1,
val totalDeposit:Long=-1,
val material:Int= Material.NONE.type,
val depositTime:LocalDateTime = LocalDateTime.now(),
val pending:Long = -1,
val isDeposited:Boolean=false,
)
What is the reason for this issue,I want to only return these three
things, and store the result subtraction result of totalDeposit and
quantity in pending column to update the table but , It give me error
to store the depositMaterial
You are returning a list of Results from getPending, not an individual DepositMaterial. But the save method requires a single object to save. Try only requesting one object from getPending by changing the return signature.
depositRepository.getPending
returns a list of Entities.
depositRepository.save(upPending)
takes a single Entity to save in the database.
Solution:
Either change your save(upPending) method to saveAll(upPending), or update your getPending repo method to return a unique Entity object.

Override serializer field from child serializer Django Rest Framework

Let's say I have two serializers, UserSerializer and EmployeeSerializer. Where Employee extends User. I want to override a field that is currently declared within UserSerializer from EmployeeSerializer.
From my understanding, you could achieved this via extra_kwargs, but it doesn't seem to work in my case and still getting required field error when I try to POST data to the server.
class UserSerializer(serializers.ModelSerializer):
username = serializers.CharField(required=True, max_length=20, allow_blank=False, allow_null=False)
class Meta:
model = User
fields = "__all__"
class EmployeeSerializer(UserSerializer):
class Meta:
model = User
fields = "__all__"
extra_kwargs = {
'username': {'required': False}
}
You have extends EmployeeSerializer from UserSerializer and in UserSerializer you have explicitly declared the username field is required True. Thus you can't make it required: False in extra_kwargs dict, in fact it will not work as Django rest framework documentation says,
Please keep in mind that, if the field has already been explicitly declared on the serializer class, then the extra_kwargs option will be ignored.
check this link for elaborate understanding.

Not raise exception on serializer with partial = true

As you see on the code. The exception does not raise when i add partial=True, It work ok with partial=False
Rest django framework
from rest_framework import serializers
class AField(serializers.Serializer):
afield = serializers.CharField()
xfed = serializers.CharField()
class BField(serializers.Serializer):
bfield = AField(many=True, required=False)
data = {
"bfield":[{},{}]
}
BField(data=data, partial=True).is_valid(raise_exception=True)

why does django-filter not work as expected

I have the below views.py file for my class based view.
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from .permissions import IsOwner, IsNotBlacklistedUser
from rest_framework import filters
from django_filters import rest_framework as filters_django
from core.models import Book
from .serializers import BookSerializer, AllBookSerializer
class BookApiView(APIView):
authentication_classes = (JSONWebTokenAuthentication, )
permission_classes = (IsAuthenticated, IsNotBlacklistedUser)
filter_backends = (filters_django.DjangoFilterBackend,)
filterset_fields = ('title',)
def get(self, request):
books = Book.objects.filter(
user=request.user.id, is_published=True).order_by('-title')
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
def post(get, request):
data = request.data
serializer = BookSerializer(data=data)
if serializer.is_valid():
serializer.save(user=request.user)
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
I am unable to see any filter option when i load this view in the django rest framework UI . I am not sure how i should be doing this. Can someone point out what i might have to do extra to get this working . I have also added 'django_filters' to my settings.py file.
Thanks in advance.
You can either use ViewSets.
class BookApiViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
authentication_classes = (JSONWebTokenAuthentication, )
permission_classes = (IsAuthenticated, IsNotBlacklistedUser)
filter_backends = (filters_django.DjangoFilterBackend,)
filter_fields = ('title',)
or generic APIViews
class BookListCreateAPIView(generics.ListCreateAPIView):
authentication_classes = (JSONWebTokenAuthentication, )
permission_classes = (IsAuthenticated, IsNotBlacklistedUser)
filter_backends = (filters_django.DjangoFilterBackend,)
filter_fields = ('title',)
or you can extend GenericAPIView and write filters manually.
class BookApiView(GenericAPIView):
authentication_classes = (JSONWebTokenAuthentication, )
permission_classes = (IsAuthenticated, IsNotBlacklistedUser)
filter_backends = (filters_django.DjangoFilterBackend,)
filter_fields = ('title',)
queryset = self.filter_queryset(self.get_queryset())
def get(self, request, *args, **kwargs):
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
Note: I didn't test codes you may need to tweak little.

Resources