django acces model field by string - django

I was wondering if it is possible to acces a field in a djangomodel from a string. Letme give you an example:
class:
class Resource(models.Model):
town = models.ForeignKey(Town, unique=True)
coin = models.IntegerField()
wood = models.IntegerField()
iron = models.IntegerField()
grain = models.IntegerField()
stone = models.IntegerField()
Now somewhere in my other code, i would like to acces a field like this
example="coin"
resources = Resource.objects.get(town="some town"):
resources.example
I know the resources.example doesnt work, i was wondering if there was some way to achieve that?
With kind regards,
Hans de Jong

You can access an attribute of any object in python by name using the getattr built-in function
example="coin"
resources = Resource.objects.get(town="some town"):
getattr(resources, example)

Related

Where and how put my business logic in django

A friend recommended that I read the book two scoops Django and I was amazed at the recommendations he makes for a robust and well-designed Django project. This reading created a doubt in me and it is where I put the business logic, I give an example. Suppose I have two models:
models.py
class Sparks(models.Model):
flavor = models.CharField(max_length=100)
quantity = models.IntegerField(default=0)
class Frozen(models.Model):
flavor = models.CharField(max_length=100)
has_cone = models.BooleanField()
quantity_sparks = models.IntegerField(default=0)
Let's suppose that every time I add a frozen, if it has sparks, I have to subtract it from the Sparks model and check that there is an available quantity. In the book they recommend putting this logic in models.py or forms.py. If create some model required modify data from another model where should I do it?
Your data model is lacking, that's the likely source of uneasiness.
class Flavor(models.Model):
name = models.CharField(max_length=100)
class Sparks(model.Model):
flavor = models.ForeignKeyField(Flavor, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
class Frozen(model.Model):
# This maybe should be a OneToOne, can't tell from your description.
sparks = models.ForeignKeyField(Sparks)
has_cone = models.BooleanField()
Then you'd do
frozen_instance = Frozen.objects.get()
frozen.sparks.quantity # This has replaced frozen_instance.quantity_sparks

Is there any possible solution for getting more than one value inside function in django?

I am creating a blog application using Django and I am also very much new to django.
This is the models I created
class categories(models.Model):
Title = models.CharField(max_length=40, default='GST')
class Blog(models.Model):
User = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
Date = models.DateTimeField(default=datetime.now)
Blog_title = models.CharField(max_length=255)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='likes',blank=True)
Description = RichTextUploadingField(blank=True, null=True,config_name='special')
Blog_image = models.ImageField(upload_to='blog_image', null=True, blank=True)
Category = models.ForeignKey(categories,on_delete=models.CASCADE,related_name='blogs')
I was wondering How to count the total no of blog present under a particular category?
I want to track a specific count rate for all Categories...
Done something like this in my model
def categories_count(self):
for a in categories.objects.all():
categories_count = Blog.objects.filter(Category__Title=a.Title).count()
return categories_count
But it is returning only one value...Can anyone suggest me with some suitable codes to resolve this...
Thank you
You can get a list of tuples of category title and blog count with the following query:
categories.objects.annotate(blog_count=Count('Categories')).values_list('Title', 'blog_count')

Django: Confused about backwards relations in views

I have object CarMaker:
class CarMaker(models.Model):
name = models.CharField(max_length=100)
And object CarModel stored in variable car_inst:
class CarModel(models.Model):
maker = models.ForeignKey(CarMaker, on_delete=models.CASCADE)
name = models.CharField(max_length=50, null=False, blank=False)
serial_number = models.CharField(max_length=50)
car_inst = CarModel.objects.get(id=foo)
I need to get the CarMaker that "owns" it.
I tried with:
maker = CarMaker.objects.get(id__in=car_inst.id)
This doesn't work. I've seen examples online of using backwards relations along the lines of:
maker = carmaker.carmodel_set.all()
But that didn't work either. What am I doing wrong here?
To get maker of car_inst you can just use car_inst.maker.
Reverse relations using in case you need to get list of cars related with specific maker maker.carmodel_set.all() this will give you all car models of the selected maker.
Let's take it step by step:
Get the CarModel object for which you want the CarMaker for :
car_model = CarModel.objects.get(id=foo)
Now, let us get the CarMaker associated with this object:
car_maker = car_model.maker

Is there a way to refer to only some fields in a Django ForeignKey?

I believe this is best explained by an example. So, I am making a program for saving weightlifting results for international and national competitions. Below is a (weight)lifter model:
class Lifter(Person):
# Changed from dateTime, as we don't need time of birth
birth_date = models.DateField(null=True)
gender = models.CharField(max_length=10, choices=Gender.choices(),
null=True)
club = models.ForeignKey('Club', null=True)
I would like to connect the lifter model to the InterntionalResult model:
class InternationalResult(models.Model):
lifter = models.ForeignKey(Lifter, null=True)
body_weight = models.FloatField(verbose_name='Kroppsvekt', null=True)
# International group can be (for example) "A" or "B"
group = models.CharField(max_length=5, verbose_name='kategori')
snatch = models.IntegerField()
clean_and_jerk = models.IntegerField()
total = models.IntegerField()
However, lifter has a ForeginKey to group (club = models.ForeignKey('Club', null=True)). When I connect Lifter to InternationalResult, I would like to exclude this ForgeinKey, but still connect Result to the rest of Lifter. This is because international competitions don't have clubs in the same way.
Is there a way to do this, or should I just create a new InternationalLifter-model?
Thank you for your time!
What are you trying to do with it? Is this going to be displayed in a template? The easiest way to "exclude" a field is to just not render it, or not use it in general. Don't worry about performance, foreign-key relations are only fetched when you evaluate them.

Pre-Populating Model-Formsets With Multiple Model Instances

I am building a football predictions app whilst learning django and have the following models:
class Team(models.Model):
Name = models.CharField(max_length=30)
class Fixture(models.Model):
HomeTeam = models.ForeignKey(Team, related_name='HomeTeamRef')
AwayTeam = models.ForeignKey(Team, related_name='AwayTeamRef')
HomeTeamScore = models.IntegerField(null=True, blank=True)
AwayTeamScore = models.IntegerField(null=True, blank=True)
Date = models.DateField()
class Player(models.Model):
User = models.ForeignKey(User)
DefaultHomeScore = models.IntegerField()
DefaultAwayScore = models.IntegerField()
class Prediction(models.Model):
Fixture = models.ForeignKey(Fixture)
HomeTeamScore = models.IntegerField()
AwayTeamScore = models.IntegerField()
Date = models.DateTimeField()
Player = models.ForeignKey(Player)
I have many fixture objects populated and have been using model formsets based on the Prediction model to render a view which allows the user to enter scores.
The problem is that they must choose which fixture the prediction relates to. I would like to pre-populate this so they get a list of fixtures and just enter the hometeamscore and awayteamscore. This involves pre-poulating the Prediction.Fixture field and Prediction.Player field but I am unsure on how to go about this?
Any help is much appreciated.
Edit: The problems seems to be how to pass multiple instances of Fixture into a Prediction model formset, I have seen examples of passing one but would like to do this all in one go.
I also would like the user to be able to make one Prediction per Fixture.
I think this is what you are looking for:
https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#using-initial-data-with-a-formset
Your code would look something like this:
initial_data = []
for fixture in fixtures:
initial_data.append({'Player':player,'Fixture':fixture})
formset = MyPredictionFormset(initial=initial_data)
P.S. Not to be pedantic, but your field names are not PEP 8 compliant. They should be lowercase with underscores, but it's your call. (http://www.python.org/dev/peps/pep-0008/)