Can not query foreign key related objects using _set | Django? - python

can not access foreignkey related objects , showing error
i have crated instance of Hospital and Availablity , But while querying using H1.availablity_set.all()
//error
'Hospital' object has no attribute 'availablity_set'
models.py
class Hospital(models.Model):
name = models.CharField(max_length = 256)
address = models.CharField(max_length=256,null=True, blank=True)
phone = models.CharField(max_length=10)
city = models.ForeignKey(City, on_delete=models.CASCADE, related_name = 'City')
def __str__(self):
return self.name
class Availablity(models.Model):
hospital = models.ForeignKey(Hospital, on_delete = models.CASCADE, related_name='availablities')
facility = models.ForeignKey(Facility, on_delete= models.CASCADE, related_name='facilities')
updated_at = models.DateTimeField(auto_now=True)
total = models.IntegerField(default=0)
available = models.IntegerField(default=0)
code

For your hospital field of the Availablity (sec), you used related_name='availablities' [Django-doc], this is the name of the relation in reverse, you thus access the Availabilitys for a Hospital:
my_hospital.availablities.all()
Your model classes and related names have some spelling mistakes. Consider renaming Availablity to Availability, related_name='availablities' to related_name='availabilities'. Furthermore it (usually) does not make much sense to give the related_name the same name is the ForeignKey itself, since that is how you query in reverse. It is thus better to rename the relaed_name to:
class Hospital(models.Model):
# …
city = models.ForeignKey(
City,
on_delete=models.CASCADE,
related_name='city_hospitals'
)

Related

message_set of Django model

i'm new with Django and as I read the code, I don't understand the message_set attribute of Django model(called Room):
def room(request, pk):
room = Room.objects.get(id=pk)
**room_messages = room.message_set.all()**
participants = room.participants.all()
portion of Models:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(
User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
If you define a ForeignKey from Message to Room, Django will add a relation in reverse to the from the Room model to its related Messages. By default this relation is named modelname_set with modelname the name of the origin of the model. You can specify another name by overriding the related_name=… parameter [Django-doc].
If you thus access the relation in reverse, you get all Message objects with room as there room, an equivalent query to room.message_set.all() is thus Message.objects.filter(room=room).

Django Rest API ManyToMany gives nothing [] in API

at the moment I try to get recipes from my API. I have a Database with two tables one is with recipes and their ids but without the ingredients, the other table contains the ingredients and also the recipe id. Now I cant find a way that the API "combines" those. Maybe its because I added in my ingredient model to the recipe id the related name, but I had to do this because otherwise, this error occurred:
ERRORS:
recipes.Ingredients.recipeid: (fields.E303) Reverse query name for 'Ingredients.recipeid' clashes with field name 'Recipe.ingredients'.
HINT: Rename field 'Recipe.ingredients', or add/change a related_name argument to the definition for field 'Ingredients.recipeid'.
Models
from django.db import models
class Ingredients(models.Model):
ingredientid = models.AutoField(db_column='IngredientID', primary_key=True, blank=True)
recipeid = models.ForeignKey('Recipe', models.DO_NOTHING, db_column='recipeid', blank=True, null=True, related_name='+')
amount = models.CharField(blank=True, null=True, max_length=100)
unit = models.CharField(blank=True, null=True, max_length=100)
unit2 = models.CharField(blank=True, null=True, max_length=100)
ingredient = models.CharField(db_column='Ingredient', blank=True, null=True, max_length=255)
class Meta:
managed = True
db_table = 'Ingredients'
class Recipe(models.Model):
recipeid = models.AutoField(db_column='RecipeID', primary_key=True, blank=True) # Field name made lowercase.
title = models.CharField(db_column='Title', blank=True, null=True, max_length=255) # Field name made lowercase.
preperation = models.TextField(db_column='Preperation', blank=True, null=True) # Field name made lowercase.
images = models.CharField(db_column='Images', blank=True, null=True, max_length=255) # Field name made lowercase.
#ingredients = models.ManyToManyField(Ingredients)
ingredients = models.ManyToManyField(Ingredients, related_name='recipes')
class Meta:
managed = True
db_table = 'Recipes'
When there is no issue it has to be in the serializer or in the view.
Serializer
class IngredientsSerializer(serializers.ModelSerializer):
# ingredients = serializers.CharField(source='ingredients__ingredients')
class Meta:
model = Ingredients
fields = ['ingredient','recipeid']
class FullRecipeSerializer(serializers.ModelSerializer):
ingredients = IngredientsSerializer(many=True)
class Meta:
model = Recipe
fields = ['title','ingredients']
View
class FullRecipesView(generics.ListCreateAPIView):
serializer_class = FullRecipeSerializer
permission_classes = [
permissions.AllowAny
]
queryset = Recipe.objects.all()
This is at the moment my output
But I want e.g. the recipe with id 0 and all the ingredients which have also recipe id 0.
I really hope that you can help me. Thank you so much!
From the doc of ForeignKey.related_name,
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'.
So, change the related_name of Ingredients.recipeid field to
class Ingredients(models.Model):
# rest of the fields
recipeid = models.ForeignKey(
'Recipe',
models.DO_NOTHING,
db_column='recipeid',
blank=True,
null=True,
related_name="ingredients_ref" # Changed the related name
)
Then, migrate the database using python manage.py makemigrations and python manage.py migrate
Then, update your FullRecipeSerializer class as,
class FullRecipeSerializer(serializers.ModelSerializer):
ingredients_forward = IngredientsSerializer(many=True, source="ingredients")
ingredients_backward = IngredientsSerializer(many=True, source="ingredients_ref")
class Meta:
model = Recipe
fields = ['title', 'ingredients_forward', 'ingredients_backward']
Note that, here I have added two fields named ingredients_forward and ingredients_backward because there existing two types of relationships between Recipe and Ingredients and I am not sure which one you are seeking.

Django - limit choices to foreign key

I have the following model in Django
class Transfer(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, limit_choices_to={'is_accepted':True})
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to filter the users based on is_accepted field. The problem is, that this field is declared in a model called Employee, which is in onetoone relationship with user.
Is there any possibility to reach Employee fields and filter them in this manner?
You can normally define a filter like:
class Transfer(models.Model):
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
limit_choices_to={'employee__is_accepted': True}
)
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)

django model field depend on the value of another field

The use case of my application is I will have various fields to fill and among them one is Industry field and another is Segment Field for brand. The industry field is like category that brand falls into. So, if i choose the industry as Health Care for XYZ brand then the segment field should show the items like 'Ayurveda', 'Dental Clinics' (all health care related items). Basically, its like sub-category.
Here is a sample model
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Industry'
verbose_name_plural = 'Industries'
def __str__(self):
return self.name
class Segment(models.Model):
industry = models.ForeignKey(Industry, related_name='segment', on_delete=models.CASCADE)
name = models.CharField(max_length=150, blank=True, null=True)
class Meta:
verbose_name = 'Segment'
verbose_name_plural = 'Segments'
def __str__(self):
return f'{self.industry.name} - {self.name}'
class BusinessModel(models):
industry = models.ForeignKey(Industry, blank=False, null=False, related_name='industry', on_delete=models.CASCADE)
# segements = models.ForeignKey()
total_investment = models.CharField() # will be choice field
This is a simple model and I have not created Segment model as I am not sure how to approach to this problem. I am just curios to know, if for such case, do i have to something special in models.py or in the view side. Such type of things get arise during development phase, thus, I want to be clear on problem solving pattern in django.
UPDATE
https://www.franchisebazar.com/franchisor-registration here if you choose industry inside Business model section, the segment will be updated accordingly.
You can have a 3 model design like
class Industry(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Segment(models.Model):
name = models.CharField(max_length=150, blank=True, null=True)
class Mapping(models.Model):
industry = models.ForeignKey(Industry)
segment = models.ForeignKey(Segment)
You need to define relations between your models. You can find documentation about ManyToMany relation here which is suitable in your case.
you can use ChainedForeginKey.. Check the below links
customizing admin of django to have dependent select fields
https://django-smart-selects.readthedocs.io/en/latest/installation.html

Django-tables2: How to use accessor to bring in foreign columns?

I've tried reading the docs and previous answers to this question without much luck.
I've got a bunch of student-course registrations and I'd like to see some of those selected registrations in conjunction with some of the attributes of the students. No luck so far...I'd request your advice!
Here's the model:
class Student(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
netID = models.CharField(max_length=8)
class Registration(models.Model):
student = models.ForeignKey(Student)
course = models.ForeignKey(Course)
attendance_M = models.BooleanField(default=False)
attendance_Tu = models.BooleanField(default=False)
and here is the tables.py:
class AttendanceTable(tables.Table):
netID = tables.Column(accessor='Student.netID')
first = tables.Column(accessor='Student.first_name')
last = tables.Column(accessor='Student.last_name')
class Meta:
model = Registration
attrs = {"class": "paleblue"}
fields = ('attendance_M', 'attendance_Tu',)
sequence = ('netID', 'first', 'last', 'attendance_M', 'attendance_Tu',)
While I'm getting data on the attendance values, there's nothing from the student foreign columns.
netID First Last Attendance M Attendance Tu
— — — ✔ ✘
And it's the same deal if I start the Table with model = Student and use accessors against the Registration table, it's the same deal.
I feel like I'm missing something very conceptual and crucial -- please guide me!
The model name in the accessor parameter of the column should be lowercase.
Use accessor='student.netID' instead of accessor='Student.netID'.
When using the accessor parameter, you have to use the field name stated in the Model that has the foreign key, and then select which field from that table you want to use.
So, for these models:
#models.py
class Description_M(models.Model):
id_hash = models.CharField(db_column='Id_hash', primary_key=True, max_length=22)
description = models.CharField(db_column='Description', max_length=255, blank=True, null=True)
class GeoCodes(models.Model):
geo = models.CharField(db_column='Geo', primary_key=True, max_length=5)
city_name = models.CharField(db_column='City', max_length=150, blank=True, null=True)
class RefSources(models.Model):
id_source = models.IntegerField(db_column='Id_source', primary_key=True,)
source_name = models.CharField(db_column='Source', max_length=150, blank=True, null=True)
class Price(models.Model):
id_hash = models.ForeignKey(Description_M, models.DO_NOTHING, db_column='Id_hash')
date= models.ForeignKey(DateTime, models.DO_NOTHING, db_column='Date')
geo = models.ForeignKey(GeoCodes, models.DO_NOTHING, db_column='Geo')
id_source = models.ForeignKey(RefSources, models.DO_NOTHING, db_column='Id_source') # Field name made lowercase.
price = models.FloatField(db_column='Price',primary_key=True, unique=False,default=None)
When using the foreign key to pull fields from that table, you have to:
class price_table(tables.Table):
description = tables.Column(accessor = 'id_hash.description')
city = tables.Column(accessor = 'geo.city_name')
source = tables.Column(accessor = 'id_source.source_name')
class Meta:
model = Price
fields = ['date','price']
sequence = ['description ','date','city ','source','price']
template_name = 'django_tables2/bootstrap.html'

Categories

Resources