Getting value of a ForeignKey instead ID - django

I have to pass a ForeignKey object in a json response, im doing it like this:
data = {}
p = Bets.objects.create( bet_id=request.POST['team'],number=number)
data['success'] = p
return HttpResponse(json.dumps(data), content_type='application/json')
bet_id field is a ForeignKey and number is a CharField, if in data['success'] I pass p.number i can pass it with no troubles, but when I pass p.bet_id I get the id of that ForeignKey, I need to get the value, I'm trying with lookup fields with p.bet_id__name but i get the following error:
'Bets' object has no attribute 'bet_id__name'
My models:
class Teams(models.Model):
name = models.CharField(max_length=100)
class Bets(models.Model):
bet = models.ForeignKey(Teams)
number = models.CharField(max_length=255)
how can I achieve get the value instead the id?

You'll want to use:
data['success'] = p.bet.name
Note that this will create a second SQL query against your db to load the Team object tied to p.bet. To save yourself a little bit of overhead, you can change this line:
Bets.objects.create( bet_id=request.POST['team'],number=number)
To this:
Bets.objects.create( bet_id=request.POST['team'],number=number).select_related('bet')

Related

Django : get() returned more than one

I have trouble to get my data from DB.
Basically one teacher can create more no of class_room each class_room contains a title and it has more number of students.
models.py
class class_room(models.model):
user = models.ForeignKey(User,related_name = 'classroom')
title = models.charField(max_length=50)
students = models.ManyToManyField(User,related_name= 'commits',symmetrical=FAlSE)
views.py
def index(request):
user = request.user
Total_class = class_room.objects.get(user = user)
students_list = Total_class.students.all()
class_name = Total_class.title.all()
return render(request,'trial/index.html,{'Total':Total_class ,'no':students_list, 'class_name ':class_name )
When i try to execute this code. i get this error get() returned more than one
Then i removed get() bcoz the user has more number of class_room so i put filter() After that i get 'QuerySet'object has no attribute 'students'
Any help appreciated :(
You have multiple objects for model class_room in the database, with the same user. Either you need to enforce the uniqueness to the user attribute in the models.
Or, you can get the students attribute of the first object in the query like,
Total_class = class_room.objects.filter(user = user).first()
students_list = Total_class.students.all()
or using index,
Total_class = class_room.objects.filter(user = user)[2]
#any element.
EDIT
As per the request of OP, I think the required queryset would be,
student_list = User.objects.filter(class_room__user=request.user)

Django validate data when updating model with primary key

I am having trouble with updating fields of a model instance. The model is as follows:
class commonInfo(models.Model):
mothers_id = models.IntegerField(primary_key=True)
date = models.DateField()
data_collector = models.CharField(max_length=50)
Essentially, I just want to do this, but it won't work because commonInfo has a user defined primary key
commonInfo_form(request.POST or None).is_valid()
Since I am updating, I am overriding date and data_collector, but not mothers_id. So I would want to do something like this, but this specific code is not working
obj = commonInfo.objects.get(pk=commonInfo_id)
form = commonInfo_form(request.POST)
date = form.cleaned_data['data_collector'] #this line is not working
data_collector = form.cleaned_data['data_collector'] #this line is not working
obj.update(**{'date':date, 'data_collector':data_collector})
any ideas? I feel like it is just those two lines that I need to fix. Or if there is a more pythonic way or built method in Django?
Just validate with isinstance. so like,
if isinstance(request.POST['date'], datetime.date) and isinstance(request.POST['data_collector'], str):
# you might have to use getattr for request.POST here, I'm not sure
# and request.POST['date'] would have to be converted from a string to datetime.date I think
date = request.POST['date']
data_collector = request.POST['data_collector']
obj.update(**{'date':date, 'data_collector':data_collector})
The process for adding a record from a form is different from updating an existing instance. All you need to do differently is indicate which instance to bind the form to when you create it, ex:
obj = commonInfo.objects.get(pk=commonInfo_id)
form = commonInfo_form(request.POST, instance=obj)

Django QuerySet: Is it possible to filter for field__is_null for FloatFields?

I want to be able to query a model for records where the is no value for a particular float field. The problem is the basic query:
Model.objects.filter(float_field__is_null=True)
returns the following error: django.core.exceptions.FieldError: Unsupported lookup 'is_null'.
To test, create the following model:
class FloatFieldModel(models.Model):
date = models.DateField()
val = models.FloatField(blank=True, null=True)
Then:
>>> objects = FloatFieldModel.objects.filter(val__is_null=True)
>>> django.core.exceptions.FieldError: Unsupported lookup 'is_null' ...
How can I filter a model for records where there is no value for a particular float field? In other words, what is the best work around?
What I want to be able to do is the set up a routine to only update rows without any values, but skip those rows already with a specified value (while making most efficient use of my database). What I was trying looks something like:
for date in dates:
try:
FloatFieldModel.objects.filter(
date=date,
val__is_null=True
).update(val=42.0)
except FloatFieldModel.DoesNotExist:
pass
I imagine I could do something like:
objects = FloatFieldModel.objects.all()
for obj in objects:
if obj.val is None and obj.date in set(dates):
obj.val = 42.0
obj.save()
I was trying for a more efficient process though, rather than on which required reading each object from the database into memory before saving.
There is lookup isnull not is_null https://docs.djangoproject.com/en/dev/ref/models/querysets/#std:fieldlookup-isnull
Model.objects.filter(float_field__isnull=True)

Django values_list with choices field

The values_list in filtering object, really helps me a lot in providing solution within django view.
My code is like the following and this one works:
values_list_ac = realdata.objects.filter(product = '1').values_list('company', 'brand', 'created_by__username')
while username is the field exists in different model outside the current realdata model.
But the following code doesn't work, for I want to show the value of ac_type, which based on choices field within the same realdata model. (I try to solve it by using the same solution which work in template):
values_list_ac = realdata.objects.filter(product = '1').values_list('company', 'brand', 'created_by__username', 'get_ac_type_display')
Is there a solution other than get_ac_type_display to show the field value?
I really appreciate for some shed of light.
Edit:
This my model:
class realdata(models.Model):
company = models.CharField(max_length=60, verbose_name="Company")
brand = models.CharField(_('brand'), max_length=60)
model = models.CharField(max_length=60)
type_choices = (
(u'1', u'Inverter'),
(u'2', u'Non-Inverter'),
)
ac_type = models.CharField(max_length=60, verbose_name="Type", choices=type_choices)
created_by = models.ForeignKey(User)
Many Thanks!
The values_list function will just get the values stored in the database. When defining choices on your model's field, it will store the first value of the tuple, hence this will be what you'll retrieve.
This means that you have to look at the choices tuple to determine the display value for the item. The purpose of the get_foo_display is to give you this human-readable value, but it needs a model instance to work on.
So, a solution to resolving this yourself would be to inspect the choices, and convert the data accordingly. The following should be able to do this:
result = []
for p in realdata.objects.filter(product='1').values_list(
'company', 'brand', 'created_by__username', 'ac_type'):
choice = {k: v for k, v in realdata.type_choices}[p[-1]]
result.append(list(p[:-1]) + [choice])
The result variable will contain the converted list. The new variable is needed because the values_list function will return a list of tuples; the latter being unmutable. Also, take care to have the value you'll want to resolve as the last item in your values_list call, or adapt the above to match.

Django: Getting category from add in view

I have this view, right:
def thisviewright(request,pk):
theadd = adds.objects.filter(id=pk)
theaddlist = adds.objects.filter(category=add.category)
return render_to_response..
And i'm trying to get the category so i display all other adds that have the same category.
As i'm not passing the category from a URL, i have to get it from the add, who's ID i am passing.
But i'm getting an error:
Queryset has no attribute Category
The model is as follows:
class adds(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('categories')
...
class categories(models.Model):
title = models.CharField(max_length=255)
So long question short, how do i get the related adds from the same category by using the category from the object i'm passing?
In the first line of the view, you're returning a queryset, not an object. While this queryset will contain only one objec, others constructed using a filter will have multiple members.
To return an object as opposed to a queryset with that line, use either of the following lines:
theadd = adds.objects.get(id=pk)
theadd = adds.objects.filter(id=pk)[0]
You should only ever use the first on unique indexed properties (i.e. id), as it will fail with an error if there is more than one object that matches the criterion.