i have the following models
class SchoolClass(models.Model):
id = models.AutoField(primary_key = True)
class_name = models.TextField()
level = models.IntegerField()
taught_by = models.ManyToManyField(User,related_name="teacher_teaching",through='TeachSubject')
attended_by = models.ManyToManyField(User,related_name='student_attending')
def __unicode__(self):
return self.class_name
class Meta:
db_table = 'classes'
class Relationship(models.Model):
rChoices = (
(1,'Mother'),
(2,'Father'),
(3,'Guardian'),
)
parent = models.ForeignKey(User,related_name='parent')
student = models.ForeignKey(User,related_name='child')
relationship = models.IntegerField(choices= rChoices)
#add in __unicode__ for admin name
class Meta:
unique_together = ('parent','student')
db_table = 'relationship
I have the the pk of the class, and I want to find out who are the parents of the students in the selected class.
My feeble attempt is:
selected_class = SchoolClass.objects.get(pk=class_id)
studs = selected_class.attended_by.all().select_related()
r = Relationship.objects.filter(student__in=students)
parents = [.parent for p in r]
Now, I am just curious if there is a shorter or more efficient way of doing this(i'm sure missed something in the docs) ?
This should work
parents = Relationship.objects.filter(student__schoolclass__id=class_id).values_list('parent', flat=True)
"To refer to a "reverse" relationship, just use the lowercase name of the model". (docs)
Related
class Item(models.Model):
name = models.CharField(max_length=20)
class Meals(models.Model):
name = models.CharField(max_length=50)
ingredients = models.ManyToManyField(Item, through='MealRecipe')
class Menu(models.Model):
name = models.CharField(max_length=50)
meals = models.ManyToManyField(Meals,through='CompMenu')
class CompMenu(models.Model):
TYPE_COMP = (
('B', 'Breakfast'),
('L', 'Lunch'),
('D', 'Dinner')
)
menu = models.ForeignKey(Menu)
meal = models.ForeignKey(Meals)
type = models.CharField(max_length=1, choices=TYPE_COMP)
class MealRecipe(models.Model):
meal = models.ForeignKey(Meal)
item = models.ForeignKey(Item)
qty = models.IntegerField()
If i need to serialze queryset how can i do it, there is no documentation about it, i need a JSON with Item_id, Item_name, MealRecipe_qty. Do i have to serialze all models ? I need this to manipualte the recipe quantities on the front end based on the selected menu.
receipes = MealRecipe.objects.filter(meal__in=meals_of_menu)
for receipe in receipes:
name = receipe.item.name
qty = receipe.qty
OR
MealRecipe.objects.filter(meal__menu=some_menu_instance).distinct()
I cannot figure out how to pass the result o this query to the front end
For your requirements of Item_id, Item_name, MealRecipe_qty, you will need to serialize the MealRecipe model and the Item model.
Also give a related name to item in MealRecipe model
class MealRecipe(models.Model):
meal = models.ForeignKey(Meal)
item = models.ForeignKey(Item,related_name='qty')
qty = models.IntegerField()
And your serializers will be
class MealRecipeSerializer(serializers.ModelSerializer):
class Meta:
model = MealRecipe
fields = ('qty')
class ItemSerializer(serializers.ModelSerializer):
qty = MealRecipeSerializer()
class Meta:
model = Item
fields = ('id','name','qty')
Also if you are passing a queryset to a serializer do it as, MealRecipeSerializer(many=True)
I am facing a very weird issue with Django ORM. I am having a below queryset which is expected to return single object (as my_unique_key is unique value), but it is returning multiple instance of the same object (check list of primary keys):
my_model_queryset = MyModel.objects.filter(q, obj_key='my_unique_key')
# print my_model_queryset.values_list('id', flat=True)
# [63, 63, 63]
where q is Q() function with content:
some_keys = [u'yJodCsWTTYyi1NMW', u'MOAKea3MSVilbxVU', u'ZXy9ONNQ1MBAMzFT',
u'cuDAuxnAFiuItzDR', u'ZzULRBixdpW9MzC8', u'pYsXxXET0mTPgzl8',
u'C4LmGqhZeILPpgAq', u'gxbkRaMKxySOfkIm']
primary_keys = [6273L, 5974L, 6342L, 4076L, 4490L, 2892L, 3921L, 1554L, 1046L,
5977L, 5946L, 6269L]
q = (Q(cf_object__obj_key__in=some_keys)|
Q(related_my_mapping__cf_object__obj_key__in=some_keys)|
Q(id__in=primary_keys))
My model structure is like:
class MyModel(models.Model):
obj_key = models.CharField(max_length=50, unique=True)
cf_object = models.ForeignKey('CFModel', null=True, related_name='related_my_model')
# ...blah...blah...blah...
class Meta:
db_table = 'my_model'
class CFModel(models.Model):
obj_key = models.CharField(max_length=50, unique=True)
# ...blah...blah...blah...
class Meta:
db_table = 'cf_model'
class MyModelCFModelMapping(models.Model):
my_object = models.ForeignKey('MyModel', null=True, related_name='related_my_mapping')
cf_object = models.ForeignKey('CFModel', null=True, related_name='related_my_mapping')
# ...blah...blah...blah...
class Meta:
db_table = 'my_model_cf_model_mapping'
However, it works perfectly fine if I remove one condition from my q function as:
q = (Q(cf_object__obj_key__in=some_keys)|
Q(id__in=primary_keys))
Any idea on why Django is behaving unexpectedly will be helpful?
I am using serializers.GeoFeatureModelSerializer to serialize Model. I have a queryset
that is creating Left Outer Join. I want to serialize related Model fields
Here is my Model
class LookupTiming(models.Model):
day = models.CharField(max_length=7)
time_1 = models.TimeField()
time_2 = models.TimeField()
class Meta:
db_table = u'lookup_timing'
class Streets(models.Model):
name = models.CharField(max_length=50)
geometry = models.GeometryField(null=True, blank=True)
objects = models.GeoManager()
class Meta:
db_table = u'streets'
def __unicode__(self):
return '%s' % self.name
class StreetTimings(models.Model):
street= models.ForeignKey(Streets)
lookuptiming = models.ForeignKey(LookupTiming)
class Meta:
db_table = u'street_timings'
queryset =
Streets.objects.filter(streettimings_lookuptiming_isnull=True)
Serializer Class
class StreetSerializer(gis_serializer.GeoFeatureModelSerializer):
class Meta:
model = Streets
geo_field = "geometry"
id_field = False
fields = ('id', 'streettimings__lookuptiming__day', other fields)
Updated
I want to show following fields on response
Streets (id)
LookupTiming (day)
I want output like this query simple is that
SELECT "streets"."id", "lookuptiming"."day" FROM "streets"
LEFT OUTER JOIN "streettimings" ON ( "streets"."id" = "streettimings"."street_id" )
LEFT OUTER JOIN "lookuptiming" ON ( "streettimings"."lookuptiming_id" = "lookuptiming"."id" )
How can i do this?
Thank you
hai i have the following query
SELECT DISTINCT P.intPartID FROM tbmstpart p, tbtrnappraisalquestion q WHERE p.intPartID = q.intPartID AND q.intTemplateID =4
my models are
class tbmstpart(models.Model):
intPartID = models.AutoField(primary_key=True,db_column="intPartID")
vchPartname = models.CharField("PartName", max_length=50,db_column="vchPartname")
def __unicode__(self):
return self.vchPartname
class Meta:
db_table = 'tbmstpart'
verbose_name = 'PartName'
verbose_name_plural = 'PartNames'
class tbmstsection(models.Model):
intSectionID = models.AutoField(primary_key=True,db_column="intSectionID")
vchSectionName = models.CharField("SectionName", max_length=50,db_column="vchSectionName")
def __unicode__(self):
return self.vchSectionName
class Meta:
db_table = 'tbmstsection'
verbose_name = 'SectionName'
verbose_name_plural = 'SectionNames'
class tbtrnappraisalquestion(models.Model):
STATUS = (
('1','Yes'),
('0','No')
)
intQuesID = models.AutoField(primary_key=True,db_column="intQuesID")
intTemplateID= models.ForeignKey(tbmsttemplate,verbose_name="Template",db_column="intTemplateID",related_name="tbmsttemplate_intTemplateID")
intSectionID= models.ForeignKey(tbmstsection,verbose_name="Section",db_column="intSectionID",related_name="tbtrnappraisalquestion_intSectionID")
intPartID= models.ForeignKey(tbmstpart,verbose_name="Part",db_column="intPartID",related_name="tbtrnappraisalquestion_intPartID")
txtQuestion = models.TextField("Question",db_column="txtQuestion")
#txtQuestion = RichTextField()
enumRating = models.CharField("Rating",max_length=5,choices=STATUS,db_column="enumRating")
enumComment = models.CharField("Comment",max_length=5,choices=STATUS,db_column="enumComment")
intOrder = models.CharField("Sequence",max_length=2,db_column="intOrder")
def __unicode__(self):
return self.txtQuestion
class Meta:
db_table = 'tbtrnappraisalquestion'
verbose_name = 'AppraisalQuestion'
verbose_name_plural = 'AppraisalQuestions'
i tried in this way
parts_list = tbmstpart.objects.filter(tbtrnappraisalquestion__intTemplateID__exact=4)
but it is throwing an error
FieldError at /opas/list_questions_test/
Cannot resolve keyword 'tbtrnappraisalquestion' into field. Choices are: intPartID, tbtrnappraisalquestion_intPartID, vchPartname
thanks in advance?
You have typo of __ in tbtrnappraisalquestion__intTemplateID rather you want tbtrnappraisalquestion_intTemplateID, with single underscore.
Change your query to
Assuming your tbmsttemplate model has intTemplateID as int primary key,
parts_list = tbmstpart.objects.filter(tbtrnappraisalquestion_intPartID__intTemplateID__intTemplateID__exact=4)
#there is no typo here, you have to do __intTemplateID__intTemplateID as your pk field in `tbmsttemplate` and FK `tbtrnappraisalquestion` are same
i tried this one as said by #Rohan. its working fine
parts_list = tbmstpart.objects.filter(tbtrnappraisalquestion_intPartID__intTemplateID__exact=4).distinct()
I have a simple foreign key relationship between two tables. I am able to save the parent, but am unable to save the child which has a foreign key to the parent. This is what my models look like:
class Product(models.Model):
month_choices = tuple((m,m) for m in calendar.month_abbr[1:])
year_choices = tuple((str(n), str(n)) for n in range(2004, datetime.now().year +2 ))
id = models.AutoField(primary_key = True)
title = models.CharField(max_length = 1024)
product_type = models.ForeignKey(ProductType)
month = models.CharField(max_length =3, choices=month_choices)
year = models.CharField(choices=year_choices, max_length = 4)
project = models.CharField(max_length = 15, null = True, blank = True)
url = models.URLField(null = True, blank = True)
export_to_xsede = models.BooleanField()
#def __str__(self):
# return str(self.id)
class Meta:
db_table = "product"
class ProductResource(models.Model):
CHOICES = (('A','A'),('B','B'),('C','C'),('D','D'),('E','E'))
id = models.AutoField(primary_key = True)
product = models.ForeignKey(Product)
resource = models.CharField(choices=CHOICES, max_length = 15)
And my views:
class PublicationForm(forms.ModelForm):
title = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
url = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
class Meta:
model = Product
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
I save the parent:
saved_publication = publications_form.save()
but am unable to save the resource form:
resource_form = ResourceForm(request.POST, instance = saved_publication)
resource_form.product = saved_publication
resource_form.save()
When I print resource_form.errors, I get:
<ul class="errorlist"><li>product<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
I have no idea why the foreign key is not getting set in this case.
I'm assuming you do not want to display the product field on the form, so you should exclude it from the form so the validation will pass:
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
exclude = ['product']
Then in the view, just set the product manually after calling is_valid(). Just be sure to pass commit=False on the form.save() so that it will not actually save to the database until after you set the product. For example
...
saved_publication = publications_form.save()
resource_form = ResourceForm(request.POST)
if resource_form.is_valid():
resource = resource_form.save(commit=False)
resource.product = saved_publication
resource.save()