Django form doesn't use the default primary key - mysql

I use IntegerField in Answer form for getting id of question page. But IntegerField doesn't get the id page, that get title of this page. I thought it because primary key is title, but not, I tried to set id = models.AutoField(primary_key=True) in Question and Answer models, but the situation is the same. This iss my form class:
class AddAnswerForm(forms.Form):
text = forms.CharField(widget=forms.Textarea)
question = forms.IntegerField()
def clean_question(self):
question_id = self.cleaned_data['question']
try:
question = Question.objects.get(id=question_id)
except Question.DoesNotExist:
question = None
return question
def clean(self):
pass
def save(self):
answer = Answer(**self.cleaned_data)
answer.save()
return answer
That's my models:
class Question(models.Model):
title = models.CharField(default='', max_length=255)
text = models.TextField(default='')
added_at = models.DateTimeField(blank=True, auto_now_add=True)
rating = models.IntegerField(default=0)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='question_user')
likes = models.ManyToManyField(User, related_name='question_like_user')
def __str__(self):
return self.title
def get_url(self):
return '/question/{}/'.format(self.id)
class Answer(models.Model):
text = models.TextField(default='')
added_at = models.DateField(blank=True, auto_now_add=True)
question = models.ForeignKey(Question, on_delete=models.SET_NULL, null=True, related_name='answer_question')
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='answer_user')
def __str__(self):
return self.text
And that's my view:
def question(request, pk):
try:
q = Question.objects.get(id=pk)
except Question.DoesNotExist:
raise Http404
a = Answer.objects.all()
u = User.objects.all()
if request.method == 'POST':
form = AddAnswerForm(request.POST)
if form.is_valid():
_ = form.save()
url = q.get_url()
return HttpResponseRedirect(url)
else:
form = AddAnswerForm(initial={
'question': q,
'answer': a,
'user': u,
})
return render(request, 'question.html',
{
'form': form,
'question': q,
'answer': a,
'user': u,
})
Thank you.

Related

django models relations getting count of given tasks

Trying to fetch a function from a table that is supposed to be there, but cannot get the value. Trying to get the amount of task that is completed.
models.py
class Task(models.Model):
title = models.CharField(max_length=55, null=True, blank=True)
slug = models.SlugField(max_length=500, unique=True, blank=True)
task_completed = models.BooleanField(default=False)
description = models.TextField(default="Task description")
start_date = models.DateTimeField()
due_date = models.DateTimeField()
checklist = models.ManyToManyField(Checklist, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Task, self).save(*args, **kwargs)
def get_url(self):
return reverse('checklists', kwargs={
'slug':self.slug
})
def __str__(self):
return self.title
#property
def num_task_completed(self):
return self.task_completed.count()
class Project(models.Model):
project_manager = models.ForeignKey(Profile, on_delete=CASCADE)
title = models.CharField(max_length=55, null=True, blank=True)
developers = models.ManyToManyField(Profile, related_name='projects')
slug = models.SlugField(max_length=500, unique=True, blank=True)
description = models.TextField(default="Project description")
date = models.DateTimeField(auto_now_add=True)
start_date = models.DateTimeField()
due_date = models.DateTimeField()
tasks = models.ManyToManyField(Task, blank=True)
teams = models.ManyToManyField(Team, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Project, self).save(*args, **kwargs)
def get_url(self):
return reverse('project_detail', kwargs={
'slug':self.slug
})
def __str__(self):
return self.title
#property
def num_task(self):
return self.tasks.count()
Then in the html is just loop through all projects
{% for projects in projects.all %}
<span class="text-small"> {{ projects.tasks.num_task_completed }} /{{ projects.num_task }}</span>
I manage to get the amount of tasks, but not the amount completed.
Use self.tasks.filter(task_completed = True).count() to get the number of completed tasks in a project.

How do I select only the fields i wanted from multiple Models in Django rest framework?

This is my models.py:
class UnitOfMeasurement(models.Model):
active = models.BooleanField(default=True)
name = models.CharField(max_length=255)
measurement_type = models.CharField(max_length=255)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=250)
abbreviation=models.CharField(max_length=10)
active = models.BooleanField(default=True)
description=models.CharField(max_length=500,blank=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
active = models.BooleanField(default=True)
bar_code = models.CharField(max_length=50, blank = True, null = True)
name = models.CharField(max_length=250)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, related_name='product')
brand = models.CharField(max_length=250)
model = models.CharField(max_length=250)
tag = models.CharField(max_length=250, null=True)
remarks = models.TextField(null=True)
gstcode = models.ForeignKey(
GSTCode, on_delete=models.CASCADE, related_name='product', null=True)
unit_of_measurement = models.ForeignKey(
UnitOfMeasurement, on_delete=models.DO_NOTHING, related_name='category')
# picture
objects=ProductManager()
# select the product where active=true & quantity<0
def __str__(self):
return self.name
So how do I need to code my serializers and views in order to get the data that returns name, category, brand, model, tag from Product Model and name from Category Model and also name and measurement_type from UnitOfMeasurement Model?
You can select fields from model in serializer as below example code for UnitOfMeasurement and use this serializer for get(retrieve) request.
class UnitOfMeasurementSerializer(serializers.ModelSerializer):
class Meta:
model = UnitOfMeasurement
fields = ["name", "measurement_type"]
Same thing you can do for rest of models.
Views depends on your use case.

none none on Django

I'm trying to get the id of another class using the filter and I'm not getting it because None appears.
This is the method used:
def total(self):
soma = Venda.objects.filter(id=self.id).aggregate(total=Sum('item__qtde', flat = True))
return soma['total']
result
Below the complete class:
class Venda(models.Model):
id = models.AutoField(u'AÇAIEX', primary_key=True)
hora_saida = models.TimeField(max_length=6)
responsavel_frete = models.CharField(max_length=14, verbose_name=u'Resp. Frete', choices = RESPONSAVEL_FRETE, default='REMETENTE')
empresa = models.ForeignKey(Empresa, on_delete=models.CASCADE)
localidade_origem = models.ForeignKey(Localidade, on_delete=models.CASCADE, verbose_name=u'Loc. Origem', related_name ='localidade_origem')
localidade_destino = models.ForeignKey(Localidade, on_delete=models.CASCADE, verbose_name=u'Loc. Destino', related_name ='localidade_destino')
cliente_origem = models.ForeignKey(Cliente, on_delete=models.CASCADE, related_name ='cliente_origem')
cliente_destino = models.ForeignKey(Cliente, on_delete=models.CASCADE, related_name ='cliente_destino')
carro = models.ForeignKey(Carro, on_delete=models.CASCADE)
motorista_principal = models.ForeignKey(Motorista, on_delete=models.CASCADE, related_name ='motorista_principal')
motorista_reserva = models.ForeignKey(Motorista, on_delete=models.CASCADE , related_name ='motorista_reserva', null=True, blank=True)
#valores default
data_venda = models.DateField(auto_now_add=True, verbose_name=u'Data',)
situacao_venda = models.CharField(max_length=10, verbose_name=u'Situação', choices = SITUACAO_VENDA, default='ATIVA')
#aba de valores teste
tipo_frete = models.CharField(max_length=10, choices = TIPO_FRETE, default='PAGO')
dinheiro = models.BooleanField()
cartao = models.BooleanField()
cartoes = models.CharField(max_length=30, choices = CARTOES, default='DINNER CLUBS', null=True, blank=True)
ano_processo = models.CharField(max_length=4, choices = CARTOES, default='VISA', null=True, blank=True)
#valor_nota = models.DecimalField(verbose_name=u'Valor Nota',
# max_digits=15, decimal_places=2, null=True, blank=True)
valor_dinheiro = models.DecimalField(verbose_name=u'Valor Dinheiro',
max_digits=15, decimal_places=2, default=Decimal('0.00'))
valor_cartao = models.DecimalField(verbose_name=u'Valor Cartão',
max_digits=15, decimal_places=2, default=Decimal('0.00'))
usuario = models.ForeignKey(User, on_delete=models.CASCADE)
agencia = models.ForeignKey(Group, on_delete=models.CASCADE, null=True, blank=True)
#produto = models.ManyToManyField(Produto, blank=False, default=None)
#staticmethod
#def autocomplete_search_fields():
# return id,
#staticmethod
def autocomplete_search_fields():
return 'id',
def __str__(self):
return str(self.id)
def imprimir(self):
return mark_safe("<a target='_blank' href='%s'>Imprimir</a>" % self.get_absolute_url())
imprimir.allow_tags = True
def get_absolute_url(self):
return reverse('venda_detail', args=[self.pk, ])
def get_venda(self):
return Venda.objects.get(pk=self.pk)
#soma o total de volume no relatorio
def total(self):
soma = Venda.objects.filter(id=self.id).aggregate(total=Sum('item__qtde', flat = True))
return soma['total']
def valortotal(self):
soma = Venda.objects.filter(id=self.id).aggregate(valortotal=Sum(F('item__produto__valor') * F('item__qtde'), output_field=FloatField()))
return soma['valortotal']
def valortotalnota(self):
return self.valor_nota
def valor_nota(self, force_insert=False, force_update=False):
valor_nota = self.valor_dinheiro + self.valor_cartao
return valor_nota
def desconto(self):
valortotal = Venda.objects.filter(id=self.id).aggregate(valortotal=Sum(F('item__produto__valor') * F('item__qtde'), output_field=FloatField()))
valor_nota = self.valor_nota
# exemplo de porcetagem return 100 - float(valor_nota.replace(",",".")) * 100 / float(valortotal['valortotal'])
if self.tipo_frete == 'CORTESIA':
return 0.00
else:
return Decimal(valortotal['valortotal']) - valor_nota()
#return valor_nota()
#return float(valortotal['valortotal'])
def clean(self, *args, **kwargs):
valortotal = Venda.objects.filter(id=self.id).aggregate(valortotal=Sum(F('item__produto__valor') * F('item__qtde'), output_field=FloatField()))
valor_nota = self.valor_nota
# if Decimal(valortotal['valortotal']) < valor_nota():
# raise forms.ValidationError("O valor do Tipo de Pagamento (dinheiro + cartão) não pode ser maior que o valor total da nota.")
class Item(models.Model):
produto = models.ForeignKey(Produto, on_delete=models.CASCADE, default=None)
qtde = models.PositiveIntegerField(null=True, blank=False)
venda = models.ForeignKey(Venda, on_delete=models.CASCADE, default=None)
class Manifesto(models.Model):
data_venda = models.DateField(default=timezone.now)
carro = models.ForeignKey(Carro, on_delete=models.CASCADE)
usuario = models.ForeignKey(User, on_delete=models.CASCADE)
def imprimir(self):
return mark_safe("<a target='_blank' href='%s'>Imprimir</a>" % self.get_absolute_url())
imprimir.allow_tags = True
def get_absolute_url(self):
return reverse('manifesto_detail', args=[self.pk, ])
#sem essa função não aparece as variaveis
def get_manifesto(self):
return Manifesto.objects.get(pk=self.pk)
def total(self):
soma = Venda.objects.filter(id=self.id).aggregate(total=Sum('item__qtde', flat = True))
return soma['total']
#Jallisson I don't see you Venda Model, but I think in your Sum() flat=True does not exist. Plus what is qtde?
If you just do Sum('item') instead of Sum('item__qtde') it might work.
one weird thing i see is:
def total(self):
soma = Venda.objects.filter(id=self.id).aggregate(total=Sum('item__qtde', flat = True))
return soma['total']
def total is inside the class Manifesto
But in you def total function you do self.id but self.id is the Id of the Manifesto class so this will never match because it is an id from a different model

How to serialize relationship in django rest?

Try to serialize this Models
Model:
class Order (models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
summ =models.CharField(max_length=15,default='0')
delivery = models.ForeignKey('Delivery')
success = models.BooleanField(default=False)
paymentMethod = models.ForeignKey('Payments')
def __unicode__(self):
return unicode(self.id)
class OrderProduct(models.Model):
order=models.ForeignKey('Order')
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
price = models.IntegerField()
product = models.ForeignKey('product.Product')
additionals = models.IntegerField(null=True,default=0)
count = models.IntegerField()
def __unicode__(self):
return self.id
class Delivery(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
delivery_time = models.DateTimeField()
delivery_adress = models.TextField()
phone = models.TextField()
def __unicode__(self):
return self.phone
class Payments(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
title = models.TextField();
def __unicode__(self):
return self.title
Serializers:
class DeliverySerializer(serializers.ModelSerializer):
class Meta:
model = Delivery
fields = ('id', 'delivery_time','delivery_adress','phone')
def create(self, validated_data):
return Delivery.objects.create(**validated_data)
class PaymentsSerializer(serializers.ModelSerializer):
class Meta:
model = Payments
fields = ('id', 'title')
def create(self, validated_data):
return Payments.objects.create(**validated_data)
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer(read_only=True)
paymentMethod = PaymentsSerializer(read_only=True)
class Meta:
model = Order
fields = ('id', 'delivery', 'paymentMethod','summ','success')
def create(self, validated_data):
deliverys_data = validated_data.pop('delivery')
paymentsMethod_data = validated_data.pop('paymentMethod')
order = Order.objects.create(**validated_data)
for delivery_data in deliverys_data:
Delivery.objects.create(order=order, **delivery_data)
for paymentMethod_data in paymentsMethod_data:
Payments.objects.create(order=order, **paymentMethod_data)
return order
View:
#api_view(['POST'])
def order_post(request, format=None):
#List all snippets, or create a new snippet.
if request.method == 'POST':
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I need to get data by 1 packet, and then write data in DB
EveryTime I get a error:
deliverys_data = validated_data.pop('delivery')
KeyError: 'delivery'
Example of JSON packet
[{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}]
You are getting KeyError: 'delivery' because you have set delivery field as read_only. If DRF finds this field in the input, it will ignore that field.
From docs on read_only argument:
Read-only fields are included in the API output, but should not be
included in the input during create or update operations. Any
'read_only' fields that are incorrectly included in the serializer
input will be ignored.
Also, since you are using paymentMethod field in the create() method, you need to tell DRF to consider that field also in the input.
So, you need to remove the read_only argument from your serializer for both delivery and paymentMethod fields so that these fields are considered when deserializing.
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer() # remove read_only argument
paymentMethod = PaymentsSerializer() # remove read_only argument
Secondly, you are sending the data incorrectly. You need to send a single order input instead of list of orders you are sending.
# send without the list
{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}
EveryTime I get a error: deliverys_data = validated_data.pop('delivery') KeyError: 'delivery'
This is to be expected since the OrderSerialzier has DeliverySerializer flagged as read_only.
If you want to get the data writable, you'll need to remove that flag first.

how to add default related record with sqlaclhemy (e.g. user belongs to group)

I have two models: AuthUser and AuthGroup, they are linked via a many2many relationship. By default I have at least 3 user "states":
unlogged -> no group
logged in -> users group
admin -> admin group
I would like to be sure that whenever a new user is added to the database, it is added to the users group too. Is there a way to get this functionality in the model defintion?
here are my table definitions
Base = declarative_base()
user_group_table = Table('auth_user_groups', Base.metadata,
Column('user_id', types.Integer(), \
ForeignKey('auth_users.id', onupdate='CASCADE', ondelete='CASCADE')),
Column('group_id', types.Integer(), \
ForeignKey('auth_groups.id', onupdate='CASCADE', ondelete='CASCADE'))
)
class AuthGroup(Base):
__tablename__ = 'auth_groups'
__table_args__ = {"sqlite_autoincrement": True}
id = Column(types.Integer(), primary_key=True)
name = Column(Unicode(80), unique=True, nullable=False)
created = Column(types.DateTime(), default=functions.now())
users = relation('AuthUser', secondary=user_group_table, \
backref='auth_groups')
def __repr__(self):
return u'%s' % self.name
def __unicode__(self):
return self.name
class AuthUser(Base):
__tablename__ = 'auth_users'
__table_args__ = {"sqlite_autoincrement": True}
id = Column(types.Integer(), primary_key=True)
login = Column(Unicode(80), default=u'', index=True)
username = Column(Unicode(80), default=u'', index=True)
_password = Column('password', Unicode(80), default=u'', index=True)
email = Column(Unicode(80), default=u'', index=True)
groups = relation('AuthGroup', secondary=user_group_table, \
backref='auth_users')
def _set_password(self, password):
self._password = bcrypt.hashpw(password, bcrypt.gensalt())
def _get_password(self):
return self._password
password = synonym('_password', descriptor=property(_get_password, \
_set_password))
#classmethod
def get_by_id(cls, id):
return DBSession.query(cls).filter(cls.id==id).first()
#classmethod
def get_by_login(cls, login):
return DBSession.query(cls).filter(cls.login==login).first()
#classmethod
def get_by_username(cls, username):
return DBSession.query(cls).filter(cls.username==username).first()
#classmethod
def get_by_email(cls, email):
return DBSession.query(cls).filter(cls.email==email).first()
#classmethod
def check_password(cls, **kwargs):
if kwargs.has_key('id'):
user = cls.get_by_id(kwargs['id'])
if kwargs.has_key('username'):
user = cls.get_by_username(kwargs['username'])
if not user:
return False
if bcrypt.hashpw(kwargs['password'], user.password) == user.password:
return True
else:
return False
usually a class constructor validates expected data upon new object creation (an INSERT in the ORM, short of any trickery to bypass the usual mechanics, always corresponds to a new instance of a mapped class created via constructor):
class AuthUser(Base):
def __init__(self, **kw):
self.groups = kw.pop('groups', None)
if not self.groups:
raise ValueError("at least one group is required!")
super(AuthUser, self).__init__(**kw)