Cannot assign "'value'": "model.attr" must be a "model" instance - python

I am new en django, I have the next models in models.py
class Persona(models.Model):
cedula_p= models.CharField(primary_key=True, max_length=10)
Nombre_p= models.CharField(User, max_length=100)
fecha_nacimiento_p= models.DateField()
#11111, User1, 01/01/1991
#22222, User2, 02/02/1992
#Others 13998 items
def __str__(self):
return "{0},{1}".format(self.cedula_p, self.Nombre_p)
class Producto(models.Model):
Nombre_prod = models.CharField(max_length=100)
precio = models.PositiveIntegerField()
def __str__(self):
return "{0}".format(self.Nombre_prod)
class compra(models.Model):
cedula_prod= models.ForeignKey(Persona, max_length=10, on_delete=models.CASCADE)
producto = models.ForeignKey(Producto, on_delete=models.CASCADE)
The forms.py is:
class formulario_compra(forms.ModelForm):
cedula_prod = forms.CharField()
#I have 14.000 elements, for that reason i don't use select o choicefield
class Meta:
model = compra
fields = '__all__'
#input test cedula_prod: 11111 or 22222
and the views.py
class crear_persona(CreateView):
model = Persona
form_class = formulario_persona
template_name = 'web1.html'
success_url = reverse_lazy('EjemploVista1')
class crear_compra(CreateView):
model = compra
form_class = formulario_compra
template_name = 'Web2.html'
success_url = reverse_lazy('EjemploVista2')
in the forms, in formulario_compra i don't use the default form for cedula_prod because would be a list with some values (14000), so, I use a charField. I need to verify that the input exists in the model Persona.cedula_p. At the moment to try to save appear:
Cannot assign "11111": "compra.cedula_prod" must be a "Persona" instance.
I try different things, but I can't solve this situation.

Because your model take ForeignKey you cannot assign character type. So, you have to use sthg like ModelChoiceField.
class formulario_compra(forms.ModelForm):
cedula_prod = ModelChoiceField(queryset=Persona.objects.all())
You can see here to check the corresponding form and model fields.

Related

drf serializer data not showing all fields data properly

id field and name field not showing in result.
in models.py:
class Group(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
admin = models.ForeignKey(User, on_delete=models.CASCADE)
member = models.ManyToManyField(User, related_name='groups_user')
def __str__(self):
return self.name
in serializers.py:
class SimpleUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','first_name', 'last_name')
class GroupSerializer(serializers.Serializer):
admin = SimpleUserSerializer()
class Meta:
model = Group
fields = ('id','name','admin')
views.py:
#api_view(['GET'])
#permission_classes((IsAuthenticated,))
def getSomeGroup(request):
allGroup = Group.objects.all().count()
randomGroupId = random.sample(range(allGroup), 3)
randomGroup = Group.objects.filter(id__in=randomGroupId)
serializer = GroupSerializer(randomGroup, many=True)
#print(serializer)
return Response(serializer.data)
the result comes like this:
[{"admin":{"id":1,"first_name":"asif","last_name":""}},{"admin":{"id":3,"first_name":"Test2","last_name":"lastname"}},{"admin":{"id":3,"first_name":"Test2","last_name":"lastname"}}]
why id and name field not showing?
class SimpleUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
First try to access all admin
#api_view(['GET'])
#permission_classes(IsAuthenticated)
def getSomeGroup(request):
randomGroup = Group.objects.all()
serializer = GroupSerializer(randomGroup, many=True)
return Response(serializer.data)
If that works there may be issue in your these two line
The Issue may be in these two lines
allGroup = Group.objects.all().count()
randomGroupId = random.sample(range(allGroup), 3)
Modify serializers.py:
class GroupSerializer(serializers.ModelSerializer):

Writing a view to allow user to add related data for a customer, like comments for example; on a single page

I have working models, forms, views and urls for a django CRUD app managing customer functions for a business. I just cant seem to figure out how to write a view to allow a user to add comments, or other data related to the customer and stored in other models using a single view and template.
So for example; for customer a, all the comments for customer a with the option to add, amend etc.. and the same for the other related models.
I understand how to do it for one I will be able to make quick progress. (old school programmer here)
Here is what I am working with - keeping it simple.
MODELS
class Emergency(models.Model):
# Fields
name = CharField(null = False, blank = False, max_length=60)
address = TextField(blank=True, null=True, help_text='Street and town', verbose_name='Address')
telephone = CharField(blank=False, null=False, unique= True, max_length=20)
relationship = CharField(choices=(('P', 'Parent'),('S', 'Son'),('D', 'Daughter'),('R', 'Relative'),('L', 'Partner')),max_length = 1,default='R')
class Meta:
ordering = ('-pk',)
def __unicode__(self):
return u'%s' % self.pk
def get_absolute_url(self):
return reverse('conform_emergency_detail', args=(self.pk,))
def get_update_url(self):
return reverse('conform_emergency_update', args=(self.pk,))
class Client(models.Model):
# Fields
surname = CharField(null = False, blank = False, max_length=30)
name = CharField(null = False, blank = False, max_length=60)
# Relationship Fields
emergencycontact = models.ForeignKey(Emergency, on_delete=models.CASCADE, name = 'Emergency Contact')
class Meta:
ordering = ('-pk',)
def __unicode__(self):
return u'%s' % self.pk
def get_absolute_url(self):
return reverse('conform_client_detail', args=(self.pk,))
def get_update_url(self):
return reverse('conform_client_update', args=(self.pk,))
class Clientnotes(models.Model):
# Fields
slug = AutoSlugField(populate_from='name', blank=True)
created = DateTimeField(auto_now_add=True, editable=False)
last_updated = DateTimeField(auto_now=True, editable=False)
note = CharField(blank=False, null=False, max_length= 300 )
# Relationship Fields
modified_by = models.ForeignKey(User, related_name='clientnotes_modified_by', on_delete=models.CASCADE, name= 'Changed by')
clientnotes = models.ManyToManyField(Client, name = 'Clients notes')
class Meta:
ordering = ('-created',)
def __unicode__(self):
return u'%s' % self.slug
def get_absolute_url(self):
return reverse('conform_clientnotes_detail', args=(self.slug,))
def get_update_url(self):
return reverse('conform_clientnotes_update', args=(self.slug,))
FORMS
class ClientForm(forms.ModelForm):
class Meta:
model = Client
fields = ['surname', 'name']
class ClientnotesForm(forms.ModelForm):
class Meta:
model = Clientnotes
readonly_fields = ['slug', 'modified_by']
fields = ['note']
VIEWS
class ClientListView(ListView):
model = Client
class ClientCreateView(CreateView):
model = Client
form_class = ClientForm
class ClientDetailView(DetailView):
model = Client
class ClientUpdateView(UpdateView):
model = Client
form_class = ClientForm
TEMPLATE NAMES
client_detail.html
client_form.html
client_list.html
I have simple views, forms and templates to list, view detail and add and it all works well - with the exception of related models because i am not able to add both models at the same time. I need a simple clear simpletons guide with what i have provided so it clicks into place.

How to return the Comment list by WorkOrder?

I have such a case:
I have a WorkOrder class:
class WorkOrder(models.Model):
workorder_num = models.CharField(max_length=64, help_text="workorder number")
name = models.CharField(max_length=32, help_text="name")
content = models.TextField(help_text="content")
And I also have a WorkOrderComment class:
class WorkOrderComment(models.Model):
"""
comment
"""
workorder = models.ForeignKey(WorkOrder, help_text="belong to which order" )
comment_user = models.OneToOneField(User, help_text="comment user")
content = models.CharField(max_length=256, help_text="content")
So, there is a requirement, I want to list the workorder comments, so I write the serializers and views:
serializer:
class WorkOrderCommentSerializer(ModelSerializer):
class Meta:
model = WorkOrderComment
fields = "__all__"
view:
class WorkOrderCommentListAPIView(ListAPIView):
serializer_class = WorkOrderCommentSerializer
permission_classes = []
queryset = WorkOrderComment.objects.filter()
But if I list workorder comment, you know it will list all the comments, no organization.
I want to through workorder to get its comments how to do with that?
You can use the nested-relationships to do that.
You do not need the WorkOrderCommentListAPIView.
You can in your WorkOrderCommentSerializer:
class WorkOrderCommentSerializer(ModelSerializer):
comments = WorkOrderCommentSerializer(many=True, read_only=True)
class Meta:
model = WorkOrderComment
fields = "__all__"
Then the access WorkOrderCommentSerializer you can get what you want.

Django Rest Framework: Saving ForeignKey inside OneToOne model

I have 2 models that are OneToOne related and model that is FK to 2nd model
models.py
class Legal(TimeStampedModel):
name = models.CharField('Name', max_length=255, blank=True)
class LegalCard(TimeStampedModel):
legal = models.OneToOneField('Legal', related_name='legal_card', on_delete=models.CASCADE)
branch = models.ForeignKey('Branch', related_name='branch', null=True)
post_address = models.CharField('Post address', max_length=255, blank=True)
class Branch(TimeStampedModel):
name = models.CharField('Name',max_length=511)
code = models.CharField('Code', max_length=6)
Using DRF I made them to behave as single model so I can create or update both:
serializer.py
class LegalSerializer(serializers.ModelSerializer):
branch = serializers.IntegerField(source='legal_card.branch', allow_null=True, required=False)
post_address = serializers.CharField(source='legal_card.post_address', allow_blank=True, required=False)
class Meta:
model = Legal
fields = ('id',
'name',
'branch',
'post_address',
)
depth = 2
def create(self, validated_data):
legal_card_data = validated_data.pop('legal_card', None)
legal = super(LegalSerializer, self).create(validated_data)
self.update_or_create_legal_card(legal, legal_card_data)
return legal
def update(self, instance, validated_data):
legal_card_data = validated_data.pop('legal_card', None)
self.update_or_create_legal_card(instance, legal_card_data)
return super(LegalSerializer, self).update(instance, validated_data)
def update_or_create_legal_card(self, legal, legal_card_data):
LegalCard.objects.update_or_create(legal=legal, defaults=legal_card_data)
views.py
class LegalDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Legal.objects.all()
serializer_class = LegalSerializer
I'm trying to save this by sending FK as integer (I just want to post id of the branch), but I receive error
ValueError: Cannot assign "2": "LegalCard.branch" must be a "Branch" instance.
Is there any way to pass over only ID of the branch?
Thank you
In Django, if you only need the FK value, you can use the FK value that is already on the object you've got rather than getting the related object.
Assume you have a Legal and Branch object with id's as 1. Then you can save a LegalCard object by:
LegalCard(legal_id=1,branch_id=1,post_address="Istanbul Street No:1")
Just use legal_card.branch_id instead of legal_card.branch to get just an id, not a related object.
And depth = 1

ManytoMany relationship serializer

I've encountered a huge problem with a single Many to many relationship, Im trying to send the id's of the users to the group serializer in order for me to save them and create the group however the id is never recorded and grupos is created with nothing but saves nombre and creates the object.
Models.py
class Usuarios(models.Model):
class Meta:
db_table = "Usuarios"
idUsuario = models.AutoField(primary_key=True)
tipoUsuario = models.BooleanField(blank=False)
nombre = models.CharField(max_length=100,blank=False)
idUser = models.IntegerField(blank=False)
idEscuela = models.ForeignKey(Escuelas, on_delete=models.CASCADE)
class Grupos(models.Model):
class Meta:
db_table = "Grupos"
idGrupo = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=30,blank=False,unique=True)
idUsuario = models.ManyToManyField(Usuarios)
class idUsuarioSerializer(serializers.Serializer):
#idUsuario = serializers.IntegerField(required=True)
class Meta:
model = Usuarios
fields = ('idUsuario',)
class GrupoSerializer(serializers.Serializer):
nombre = serializers.CharField(required=True)
idUsuario = idUsuarioSerializer(many=True)
class Meta:
model = Grupos
fields = ('nombre','idUsuario')
def create(self, validated_data):
idUsuarios_data = validated_data.pop('idUsuario')
grupo = Grupos.objects.create(**validated_data)
for idUsuario_data in idUsuarios_data:
#print(**idUsuario_data)
#Usuarios.objects.create(grupo=grupo,**idUsuario_data)
grupo.idUsuario.add(**idUsuario_data)
grupo.save()
return grupo
However this saves nothing on idUsuario field and also if I do it like the documentation it gives me an error "group is not a valid keyword" or even if I use "idGrupo" it says the same, I already check other answers looks like it's not possible, already tried add method too.
I send the following json
{
"nombre": "4B",
"idUsuario":[{"id":1},{"id":2}]
}
Try something like this,
for idUsuario_data in idUsuarios_data:
grupo.idUsuario.add(idUsuario_data['id'])
grupo.save()

Categories

Resources