Django- limit_choices_to using 2 different tables - python

I fear that what I am trying to do might be impossible but here we go:
Among my models, I have the following
Class ParentCategory(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
Class Category(models.Model):
parentCategory = models.ForeignKey(ParentCategory, on_delete=models.CASCADE, )
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
Class Achievement(models.Model):
milestone = models.ForeignKey(Milestone, on_delete=models.CASCADE)
description = models.TextField( )
level_number = models.IntegerField()
completeion_method = models.ForeignKey(Category, on_delete = models.CASCADE, limit_choices_to={'parentCategory.name':'comp method'})
def __unicode__(self): # TODO:
return description[0,75] + '...'
I know the completion method field throws an error because it is not correct syntax. But is there a way to achieve the wanted result using a similar method?

Maybe this will work:
limit_choices_to={'parentCategory__name': 'comp method'}

Related

How to write __str__ func in this case?

I have a 'user' model that have a OneToOneField to User Model and another model named 'user_agent' that have a foreign key to 'user' model. How can I use 'first_name' and 'last_name' in the __str__ func?!
class users(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, default='')
user_type = models.ForeignKey(types, on_delete=models.SET_NULL, blank=True, null=True)
mobile = models.CharField(max_length=20)
active_code = models.CharField(max_length=50, blank=True)
date_send_active_code = models.DateField(default=now, blank=True)
count_send_active_code = models.IntegerField(default=0)
token = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class user_agent(models.Model):
user = models.ForeignKey(user_models.users, on_delete=models.CASCADE)
agent = models.ForeignKey(agents, on_delete=models.CASCADE)
parent = models.ForeignKey("self", on_delete=models.CASCADE, default='1')
def __str__(self):
return "(" + self.user.first_name + " " + self.user.last_name + ")"
You want self.user.user.first_name - but I kindly suggest you change your user model name to something like Profile to avoid confusion (and use CamelCase for your models names in general).
def __str__(self):
return "({} {})".format(self.user.first_name, self.user.last_name)
or if you're using python 3, use f strings:
def __str__(self):
return f"({self.user.first_name} {self.user.last_name})"
EDIT: not sure if you're asking about the user or user_agent model, if it's the user model, then just use the code above but with self.first_name and self.last_name instead.
Also, typically python classes are upper case without underscores:
class User(models.Model) and class UserAgent(models.Model)

Django two ForeignKey from same model

In Pegawai model, I need two ForeignKeys to:
Jabatan model
unit_kerja field of Jabatan model
How to apply these for my Pegawai model? Only the first one worked.
Here is my models.py:
from django.db import models
from django.urls import reverse
# Create your models here.
class UnitKerja(models.Model):
nama_unit_kerja = models.CharField(max_length=100)
def get_absolute_url(self):
return reverse("users:unitkerja")
def __str__(self):
return self.nama_unit_kerja
class Jabatan(models.Model):
nama_jabatan = models.CharField(max_length=100)
level_jabatan = models.IntegerField()
unit_kerja = models.ForeignKey(UnitKerja, on_delete=models.CASCADE, blank=True, null=True)
def get_absolute_url(self):
return reverse("users:jabatan")
def __str__(self):
return self.nama_jabatan
class Pegawai(models.Model):
nip = models.CharField(max_length=100, unique=True)
nama_pegawai = models.CharField(max_length=100)
alamat = models.CharField(max_length=255)
jabatan = models.ForeignKey(Jabatan, on_delete=models.CASCADE)
#this line#
unit_kerja = models.ForeignKey(Jabatan.unit_kerja, on_delete=models.CASCADE, blank=True, null=True)
def get_absolute_url(self):
return reverse("users:pegawai")
def __str__(self):
return self.pegawai
There is no such thing as a foreign key to a field, but you don't need it anyway. You can always access the UnitKerja instance by using multiple traversal, for example:
my_unit_kerja = my_pegawai.jabatan.unit_kerja
Or you can have a helper property, if the above is too much work:
class Pegawai(models.Model):
...
#property
def unit_kerja(self):
return self.jabatan.unit_kerja
and then simply use
my_pegawai.unit_kerja

Django - Get name of model object by iterating through class

I'm new to Python (and pretty inexperienced at programming in general), but I have an issue I can't for the life of me figure out.
I'm trying to pre-populate a field in my database with the name of an instance from another model/class in my database. The model with the field I want to pre-populate is an "instance" of the model instance from which I'm trying to grab the name, and has a foreign key to that instance.
Goal: 1) User selects the parent of the object by assigning the foreign key to the parent 2) A function grabs the name of the parent instance matching the foreign key the user selected. 3) the result from that function is used as the default value for the field.
Here's the code:
class Injury(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular injury')
name = models.CharField(max_length=200, help_text='Enter an injury or complication (e.g. respiratory failure)')
description = models.TextField(max_length=1000, blank=True, help_text='Describe the injury')
time_to_onset = models.PositiveIntegerField(blank=True, validators=[MaxValueValidator(10000)], help_text='Enter expected time from trigger until injury/complication onset')
findings = models.TextField(max_length=1000, blank=True, help_text='Enter the signs and symptoms of the injury or complication')
vitals_trends = models.TextField(max_length=1000, blank=True, help_text='Enter the vitals changes due to the injury')
class Meta:
ordering = ['name']
def __str__ (self):
return self.name
def get_absolute_url(self):
return reverse('Injury-detail', args=[str(self.id)])
class Injury_Instance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular injury')
parent_case = models.ForeignKey(PFC_Case, on_delete=models.SET_NULL,null=True)
injury_model = models.ForeignKey(Injury, on_delete=models.SET_NULL, null=True)
def set_injury_name(self):
for injuries in Injury.all()
if injury_model == injuries
break
return Injury.name
name = dislay_models.CharField(default=set_injury_name(self,Injury,injury_model), max_length=100)
triggered_by = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
def __str__ (self):
return self.name
def get_absolute_url(self):
return f'{self.id} ({self.Injury.name})'
The problem area is def set_injury_name and Injury_Instance.name
Thanks!!!
Edit:
I tried the following code, but I'm getting the error 'NameError: name 'self' is not defined'
class Injury_Instance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular injury')
parent_case = models.ForeignKey(PFC_Case, on_delete=models.SET_NULL,null=True)
injury_model = models.ForeignKey(Injury, on_delete=models.SET_NULL, null=True)
def get_injury_name(self):
return self.name
injury_name=get_injury_name(self)
name = models.CharField(default=injury_name, max_length=100)
triggered_by = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
def __str__ (self):
return self.name
def get_absolute_url(self):
return f'{self.id} ({self.Injury.name})'
You don't need to store the name of your foreign key field as you always can access it with:
self.injury_model.name
If you need to get access it just by name you can write a property in Injury_Instance model.
#property
def name(self):
return self.injury_model.name

relationships in django 2 models.py

I want to define a relationship between Book and Member through Borrow in models.py
ER
But I don't know how to define the Borrow relationship.
In the Borrow table it must be determined which books have been borrowed by who and which books have been returned on which date. Should I use another table for this date field?
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext as _
class CategoryType(models.Model):
category_name = models.CharField(max_length=200)
def __str__(self):
return self.category_name
class Book(models.Model):
name = models.CharField(verbose_name="عنوان", max_length=128)
number_of_copy = models.IntegerField(default=0)
writer = models.CharField(max_length=64)
B_category = models.ForeignKey(CategoryType, on_delete=models.CASCADE)
class Meta:
ordering = ["B_category"]
def __str__(self):
return self.name
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(member, on_delete=models.CASCADE)
books = models.ManyToManyField(Book)
def __str__(self):
return self.id
class Member(AbstractUser):
pass
I think in the Member class I should have a field containing borrow_id, but how?
It seems to me that you need to use a ManyToMany relationship with a through model (this way you can store extra information for every row of the Borrow model)
...
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(Member, on_delete=models.CASCADE)
book = models.ForeignKey(Book)
def __str__(self):
return self.id
...
class Member(AbstractUser):
borrowed_books = models.ManyToManyField(Book, through='Borrow')
Maybe this link (https://docs.djangoproject.com/es/2.1/ref/models/fields/#django.db.models.ManyToManyField.through) could clarify it more.

Django ManyToMany with through model implementation

So let's say I have these models in my Django app:
class Ingredient(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Recipe(models.Model):
name = models.CharField(max_length=100)
ingredients = models.ManyToManyField(Ingredient,
through='RecipeIngredient')
def __unicode__(self):
return self.name
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe)
ingredient = models.ForeignKey(Ingredient)
quantity = models.DecimalField(max_digits=4, decimal_places=2)
unit = models.CharField(max_length=25, null=True, blank=True)
def __unicode__(self):
return self.ingredient.name
Now I want to access a recipe's ingredients (really RecipeIngredients). Via the Django shell:
>>> r = Recipe.objects.get(id=1)
>>> ingredients = RecipeIngredients.objects.filter(recipe=r)
This seems counter-intuitive and clunky to me. Ideally I'd like to be able to have a Recipe object and get RecipeIngredients from it directly.
Is there a more elegant implementation of my models? Is there any way to improve my existing model implementation?
Use related_name, just as you would with a normal ForeignKey or ManyToManyField:
class RecipeIngredients(models.Model):
recipe = models.ForeignKey(Recipe, related_name='ingredient_quantities')
And then:
>>> r = Recipe.objects.get(id=1)
>>> ingredients = r.ingredient_quantities.all()

Categories