How to get one query from two models? - django

I have two models:
class ModManager(models.Manager):
def myfilter(self, options = dict()):
if options.has_key('not_image'):
kwargs['image__isnull'] = False
return self.filter(**kwargs)
class Model_1(models.Model):
...
objects = MyManager()
class Model_2(models.Model):
something = models.ForeignKey(Model_1)
something_else = ...
...
How to get all data from Model_2 related to Model_1 in MyManager? I want to get one query. I have so far:
in Model_1:
def get_model_2(self):
self.model_2_objs = self.model_2_set.all()
But it generates many queries when I calling get_model_2 function.

Related

How to modify the form filed data?

I have a model:
class PastStudy(Model):
grade_average = FloatField(null=True)
I have a modelform as below:
class PastStudyForm(ModelForm):
class Meta:
model = PastStudy
fields = ('grade_average', )
What I have in view:
...
if request.POST:
past_study_form = PastStudyForm(request.POST)
if past_study_form.is_valid():
return HttpResponse(past_study_form.cleaned_data['grade_average'])
else:
profile_filter_past_study_form = ProfileFilterPastStudyForm()
...
What I need is that I want to write a clean method for PastStudyForm so that in case I entered 90 as grade average, HttpResponse converts it two 0-20 grading scheme and returns 18.
I tried this and I was still getting 90 not 18
class PastStudyForm(ModelForm):
class Meta:
model = PastStudy
fields = ('grade_average', )
def clean(self):
cleaned_data = super().clean()
grade_average = self.cleaned_data['grade_average']
self.cleaned_data['grade_average'] = grade_average/5
return cleaned_data
and This:
class PastStudyForm(ModelForm):
class Meta:
model = PastStudy
fields = ('grade_average', )
def clean_grade_average(self):
grade_average = self.cleaned_data['grade_average']
data = grade_average/5
return data
However, I still get 90. I also have tried a few other methods but I still was getting 90 in HttpResponse
Maybe using clean method be wrong and I should do something else!
The real code is huge and I have summarized it in here and other aspects of the problem are not explained in here. That is why I prefer and expect to get a response in which I am advised how to it in the form definition, not other methods such as converting it in the view.
in your clean method, you assign the result of your calculation method into self.cleaned_data,
while you are returning cleaned_data not self.cleaned_data.
it is different variable.
try this instead:
self.cleaned_data = super().clean()
grade_average = self.cleaned_data['grade_average']
self.cleaned_data['grade_average'] = grade_average/5
return self.cleaned_data

Call method on Django fields

class Colour(models):
...
def colour_preview(self):
return format_html(...)
class ColourTheme(models):
colour1 = models.ForeignKey(Colour)
colour2 = models.ForeignKey(Colour)
colour3 = models.ForeignKey(Colour)
...
def preview(self):
for field in self._meta.get_fields(include_parents=False):
if (field.related_model == Colour):
field.colour_preview()
I have a ColourTheme model with multiple Colour foreign keys, and I want to call a function on each of the Colour objects referred to by those fields. The last line of code above fails. I would like to call colour_preview on all Colour fields without hardcoding them (self.colour1.colour_preview() works but not ideal).
How might I achieve this?
You cannot refer to the field in order to access related object method.
Try something like this (I haven't tested it):
class ColourTheme(models):
colour1 = models.ForeignKey(Colour)
colour2 = models.ForeignKey(Colour)
colour3 = models.ForeignKey(Colour)
...
def preview(self):
for field in self._meta.get_fields(include_parents=False):
if (field.related_model == Colour):
field_obj = field.value_from_obj(self) # To get obj reference
field_obj.colour_preview()

Django Model inheritance and access children based on category

I want to get the parent class values with each child values? How can I identify child objects to fetch?
I have the Django model structure like this.
class Category(models.Model):
name = models.CharField(max_length=80)
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
category = models.ForeignKey('Category')
class PizzaRestaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
class PastaRestaurant(Place):
extra = models.CharField(max_length=80)
When we do operation we may save the object like below. And it saved into the db as i expected. two entry in the Place table and each entry in each child object table.
a = Category()
a.name = "pasta"
b = Category()
b.name = "pizza"
a.save()
b.save()
x = PastaRestaurant()
x.address = "Pasta Address"
x.name = "Pastamonia"
x.extra = "some extra"
x.category = a
y = PizzaRestaurant()
y.address = "Pizza Address"
y.name = "Dominos"
y.serves_hot_dogs = 1
y.serves_pizza = 0
y.category = b
x.save()
y.save()
Now I need to access the like this
p = Place.objects.get(id=1)
How can I know, which objects/attributes belongs to the place objects?
So when I fetch the place with common attributes and should be able get the corresponding child objects values also.
Or any other model design work for my need?
If you want to access the child model's attributes you need to fetch it as that model, i e PizzaRestaurant or PastaRestaurant, otherwise you will only get a Place object.
If you need to get all Places regardless of subclass take a look at InheritanceManager from django-model-utils. Using this you can implement overloaded operations to perform subclass-specific actions.
django-polymorphic does this beautifully, improving the abilities to work with model inheritance like so:
from polymorphic.models import PolymorphicModel
class Place(PolymorphicModel):
...
class PizzaRestaurant(Place):
...
class PastaRestaurant(Place:
...
>>> some_place = Place.objects.create(name="Walmart")
>>> some_pizza_place = PizzaRestaurant.objects.create(name="Slice King", address="101 Main St., Bismarck, ND", category = Category.objects.first(),serves_pizza=True)
>>> some_pizza_place.instance_of(PizzaPlace)
True
>>> PizzaRestaurant.objects.all()
queryset<['Slice King',]>
>>> Place.objects.all()
queryset<['Walmart', 'Slice King',]>

Call a method as a field of ValuesQuerySet

I have a model and a method on it as follows:
class Results(models.Model):
t_id = models.TextField(blank=True)
s_result_id = models.TextField(blank=True,primary_key=True)
s_name = models.TextField(blank=True)
s_score = models.FloatField(blank=True, null=True)
... (some other fields with huge data)
def get_s_score(self):
return 100 * self.s_score
On a view, I am trying to call get_s_score method from inside values. I have to use values to avoid selecting other fields with huge data.
def all_recentsiteresults(request,t_id1):
Result = Results.objects.filter(t_id=t_id1).values('s_result_uid','s_name',get_s_score())
You can't use the model's method in the values() method. But you can use the only() method to decrease the memory usage:
Results.objects.only('s_result_id', 's_name', 's_score').filter(t_id=t_id1)

Django query related objects

I have models like this:
class A(Model):
....
class B(Model):
a = ForeignKey(A, related_name="bbb")
class C(Model)
b = ForeignKey(B, related_name="ccc")
file = FileField( ... , null=True, blank=True)
In template or in view I need a mark A row, if some C object related to A has file=None (null) .
Thanks.
If I understand correctly, try this:
for a in A.objects.all():
for b in a.bbb.all():
for c in b.ccc.filter(file__isnull=True):
a.has_c_with_null_file = True
a.save()
OR
c_without_file = C.objects.filter(file__isnull=True)
for c in c_without_file:
c.b.a.has_c_with_null_file = True
c.b.a.save()
OR
A.objects.filter(b__c__file__isnull=True).update(has_c_with_null_file=True)
If you leave off the related name, use b_set and c_set.