Django Table Join - django

I am going over the django join on to get some query set.
I have declared two model like this
class PortService(models.Model):
port=models.IntegerField()
service=models.TextField()
class Meta:
unique_together=(('port','service'),)
class ServiceDefects(models.Model):
port=models.ForeignKey('PortService')
defect_id=models.TextField()
defect_description=models.TextField()
class Meta:
unique_together=(('port','defect_id'),)
I want to get all the entry of ServiceDefects class which has a port number of 80 and service named 'Apache'. For this I wrote the query like this:
ServiceDefects.objects.filter(portservice__port=80).filter(portservice__service='Apache')
Any Help?? Thanks in advance.

The foreign key field is called port, not portservice, so you should do:
ServiceDefects.objects.filter(port__port=80).filter(port__service='Apache')
You might prefer to put both arguments in a single filter():
ServiceDefects.objects.filter(port__port=80, port__service='Apache')

You should write both conditions in a single filter:
ServiceDefects.objects.filter(port__port=80, port__service='Apache')

Related

Django Models filter only last records

I m developing a CRM using Django , my goal is to get a list of only last records of a model, my models like below
class Rapport(models.Model):
added=models.DateField(default=timezone.now,blank=True,db_index=True)
user=models.ForeignKey(User,on_delete=models.CASCADE)
image=models.ImageField(upload_to=upload_location)
image2=models.ImageField(blank=True,null=True,upload_to=upload_location2)
can_update=models.BooleanField(default=False)
note=models.PositiveIntegerField(default=0,db_index=True)
observation=models.TextField(blank=True,null=True)
class Visite(models.Model):
rapport=models.ForeignKey(Rapport,on_delete=models.CASCADE)
observation=models.TextField()
medecin=models.ForeignKey(Medecin,on_delete=models.CASCADE)
produits=models.ManyToManyField(Produit,through='produits.ProduitVisite')
priority=models.PositiveIntegerField(default=0,db_index=True)
class Medecin(models.Model):
nom=models.CharField(max_length=255,db_index=True)
telephone=models.CharField(max_length=10)
email=models.EmailField(blank=True,null=True)
commune=models.ForeignKey(Commune,on_delete=models.CASCADE)
adresse=models.CharField(max_length=255)
flag=models.BooleanField(default=False)
updatable=models.BooleanField(default=True)
contact=models.CharField(max_length=255,blank=True,null=True)
users=models.ManyToManyField(User)
I want to get only the last Visite object of each Medecin a dirty way of doing it would be like so :
last_visites=[Visite.objects.filter(medecin=medecin)[-1] for medecin in Medcin.objects.all()]
May this method will give you what you want :
medecin_last_visit_ids = Medecin.objects.values('id','visite__id').order_by('-visite__id').distinct('id')
`

Django How to generate value of attribute while initializing

I have a enum table ServiceType in my database which includes "Credit", "Investment" and "Insurance" and another table Service which have two columns - type_id and type. Is there a way to call method which will be generating value of type from value of type_id while initialization?
Should I use __init__ or maybe save?
type in Service is a ForeignKey to ServiceType
Thanks, sorry for my bad English.
So, I've tried something like this:
class Service(models.Model):
type_id = models.CharField(..)
type = models.ForeignKey('ServiceType',
to_field = 'type',
default = foo(type_id))
class ServiceType(models.Model):
type = models.CharField(..)
I've found the answer if anyone will be looking for it in future.
Things like that are managed by using signals. For above example I've used pre_save signal in function decorated as reciver.
In my understanding, reciver catches data before or after saving in database - way of doing it is based on type of signal. Those functions could basicly do anything, for example - change type of Service based on given type_id.

how to get child instance of a foreignkeyfield in a query

i have three classes. Place is foreignkey of Activity(where the activity takeplace), Park and Restarant are inherited from Place.
class Activity(Model):
place=ForeignKeyField('Place')
....
class Place(Model):
address=CharField(max_length=200)
....
class Park(Place):
ticket_price=Decimal()
....
class Restarant(Place):
manager_name=CharField(max_length=100)
how can i get the real type of 'Place' in a query on Activity,so i can get the additional attributes of child type.
activity_list= Activity.objects.all()
all the activity_list[n].place are 'Place' ,neither Park or Restarant, so i can't get 'ticket_price' or 'manager_name' directly.
i have checked the model-utils, and can't find a easy way to do this.
any help will be appreciated.
inspect.getmro(cls)
Return a tuple of class cls’s base classes, including cls, in method resolution order. No class appears more than once in this tuple. Note that the method resolution order depends on cls’s type. Unless a very peculiar user-defined metatype is in use, cls will be the first element of the tuple.
try:
import inspect
for activity in activity_list:
print inspect.getmro(activity.place)
or try :
for activity in activity_list:
print activity.place._type()
try:
activity_list= Activity.objects.all()
for act in activity_list:
for b in act.place.__class__.__bases__:
print b.__name__
I use Django Inheritance Managers for this, from django-model-utils. It allows you to do exactly what you want...you said you checked model-utils to do this, but it didn't work. It should work -- what did you try with django-model-utils? You need to add this line to the parent model of Place:
objects = InheritanceManager()
I haven't tried this with your exact model design, but have you tried something like:
places = Activity.objects.all().values_list('place_id', flat=True)
places_of_right_type = Place.objects.filter(pk__in=places).select_subclasses()
?
------ UPDATE --------
Not sure this will work, but throwing it out there as an idea...would only work for a get(), not all():
places = Activity.objects.get(pk=#).place.objects.select_subclasses()
The docs say that you can call select_subclasses() on the InheritanceManager itself, which is stored in .objects.

dynamic condition for relationship(sqlalchemy) in Flask-Admin

I'm using sqlalchemy and have two models, Article and Tag, it's a many-to-many relation.
When I add articles using Flask-Admin, I want just part of tags available (related on user permission) instead of all tags.
any idea? Thanks
Probably the best way to do this is to use dynamic relationship loaders. Simply use lazy='dynamic' in your relationship definition:
posts = relationship(Post, lazy="dynamic")
This returns you a query object instead of a collection of objects, so you can then query it directly:
posts = jack.posts.filter(Post.headline=='this is a post')
You could also achieve what you want with discriminator columns or something, but that is likely overkill.
sounds like you need ModelView.get_query:
class MyView(ModelView):
def get_query(self,*args,**kwargs):
return super(MyView,self).get_query(*args,**kwargs).filter_by(current_user.can_view=True)

How can I get access to a Django Model field verbose name dynamically?

I'd like to have access to one my model field verbose_name.
I can get it by the field indice like this
model._meta._fields()[2].verbose_name
but I need to get it dynamically. Ideally it would be something like this
model._meta._fields()['location_x'].verbose_name
I've looked at a few things but I just can't find it.
For Django < 1.10:
model._meta.get_field_by_name('location_x')[0].verbose_name
model._meta.get_field('location_x').verbose_name
For Django 1.11 and 2.0:
MyModel._meta.get_field('my_field_name').verbose_name
More info in the Django doc
The selected answer gives a proxy object which might look as below.
<django.utils.functional.__proxy__ object at 0x{SomeMemoryLocation}>
If anyone is seeing the same, you can find the string for the verbose name in the title() member function of the proxy object.
model._meta.get_field_by_name(header)[0].verbose_name.title()
A better way to write this would be:
model._meta.get_field(header).verbose_name.title()
where header will be the name of the field you are interested in. i.e., 'location-x' in OPs context.
NOTE: Developers of Django also feel that using get_field is better and thus have depreciated get_field_by_name in Django 1.10. Thus I would suggest using get_field no matter what version of Django you use.
model._meta.get_field_by_name('location_x')[0].verbose_name
You can also use:
Model.location_x.field.verbose_name
Model being the class name. I tested this on my Animal model:
Animal.sale_price.field.verbose_name
Animal.sale_price returns a DeferredAttribute, which has several meta data, like the verbose_name
Note: I'm using Django 3.1.5
If you want to iterate on all the fields you need to get the field:
for f in BotUser._meta.get_fields():
if hasattr(f, 'verbose_name'):
print(f.verbose_name)
# select fields for bulk_update : exclude primary key and relational
fieldsfields_to_update = []
for field_to_update in Model._meta.get_fields():
if not field_to_update.many_to_many and not field_to_update.many_to_one and not field_to_update.one_to_many and not field_to_update.one_to_one and not field_to_update.primary_key and not field_to_update.is_relation :
fields_to_update = fields_to_update + [field_to_update.name]
Model.objects.bulk_update(models_to_update , fields_to_update)