I have a long variable name in one of my models "xxxx_xxxx_xx_xxxxxxxx" is there an equivilent of:
xxxx_xxxx_xx_xxxxxxxx.short_description = 'xxxx'
for variables or do I have to make a method to display that? I would like to not have to use a method because I want to be able to sort by this variable in the Django admin. Thanks.
Look at the verbose field name option. It allows you use whatever name you like in the admin. There is also the verbose_name_plural for model names that have unusual plural construxions.
Related
I haven't had much luck finding other questions that helped with this, but apologies if I missed something and this is a duplicate.
I'm trying to add to some ManyToMany fields, without having to explicitly type out the names of the fields in the code (because the function I'm working on will be used to add to multiple fields and I'd rather not have to repeat the same code for every field). I'm having a hard time using ._meta to reference the model and field objects correctly so that .add() doesn't throw an "AttributeError: 'ManyToManyField' object has no attribute 'add'".
This is simplified because the full body of code is too long to post it all here, but in models.py, I have models defined similar to this:
class Sandwich(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
veggies = models.ManyToManyField(Veggie)
meats = models.ManyToManyField(Meat)
class Veggie(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
class Meat(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
Once instances of these are created and saved, I can successfully use .add() like this:
blt = Sandwich(name='blt')
blt.save()
lettuce = Veggies(name='lettuce')
lettuce.save()
tomato = Veggies(name='tomato')
tomato.save()
bacon = Meat(name='bacon')
bacon.save()
blt.veggies.add(lettuce)
blt.veggies.add(tomato)
blt.meats.add(bacon)
But if I try to use ._meta to get blt's fields and add to them that way, I can't. ie something like this,
field_name='meats'
field = blt._meta.get_field(field_name)
field.add(bacon)
will throw "AttributeError: 'ManyToManyField' object has no attribute 'add'".
So, how can I use ._meta or a similar approach to get and refer to these fields in a way that will let me use .add()? (bonus round, how and why is "blt.meats" different than "blt._meta.get_field('meats')" anyway?)
Why do you want to do
field = blt._meta.get_field(field_name)
field.add(bacon)
instead of
blt.meats.add(bacon)
in the first place?
If what you want is to access the attribute meats on the blt instance of the Sandwich class because you have the string 'meats' somewhere, then it's plain python you're after:
field_string = 'meats'
meats_attribute = getattr(blt, field_string, None)
if meats_attribute is not None:
meats_attribute.add(bacon)
But if your at the point where you're doing that sort of thing you might want to revise your data modelling.
Bonus round:
Call type() on blt.meats and on blt._meta.get_field(field_name) and see what each returns.
One is a ManyToManyField, the other a RelatedManager. First is an abstraction that allows you to tell Django you have a M2M relation between 2 models, so it can create a through table for you, the other is an interface for you to query those related objects (you can call .filter(), .exclude() on it... like querysets): https://docs.djangoproject.com/en/4.1/ref/models/relations/#django.db.models.fields.related.RelatedManager
I need to get the first name and last name of a user for a function in my views How do I do that? What is the syntax for it? I used request.user.email for the email, but I don't know see an option for a first name or last name. How do I go about doing this?
Should I import the model into the views and then use it?
There are multiple ways to get the information you require.
request.user.get_full_name(), returns the first name and last name, separated by a space.
request.user.get_short_name(), returns just the first name
You can also access the attributes directly, with request.user.first_name and request.user.last_name, but it is preferred to use the methods as the attributes may change in future versions.
The django user model has a rich set of methods, which you can read about in the reference for the auth application.
You want the first_name and last_name attributes: request.user.first_name and request.user.last_name
I'm trying to make a select box in the admin that shows a list of objects in the database, outside the current app. Here is my model
from typefaces.models import Typeface
class Word(models.Model):
text = models.CharField(max_length=200)
family_select = models.CharField(max_length=100, choices=Typeface.objects.all)
Unfortunately, Django tells me 'choices' must be an iterable (e.g., a list or tuple). But my attemps to make it iterable with iter() have yielded no success.
This is a completely wrong way to do it. Relationships between models should be specified using OneToOneFields, ForeignKeys (one-to-many field) and ManyToManyFields. You should just change the CharField to this:
family = models.ForeginKey(Typeface, related_name='words')
If you have a specific reason for not using the generally acceptable way, please elaborate on that further to get an answer for that.
Is it possible to send a field name as a variable?
The following works (Note: myqso is a filtered queryset based on a model with a field called LocTypeNum):
myqsnew = myqso.annotate(newloctypenum=F('LocTypeNum')+10)
myqsop = [{'the_new_loctypenum':p.newloctypenum} for p in myqsnew]
But I want to send LocTypeNum in as a variable. Is there a better/faster method for making calculated fields and using variables as field names? Thanks!
In this is example LocTypeNum is just a string. So you can just replace with variable:
somefield = "some_field"
SomeModel.objects.all().aggregate(somename=Sum(F(somefield))
You can even path aggragetion name as varaiable:
SomeModel.objects.all().aggregate(**{somename: Sum(F(somefield)})
I got a problem, after saving a record , for view displays model name plus record number . like in the screen shot . i want only record name appear there . thanks in advance
please help , except _rec_name , cause here i get multiples ids from multiple tables
OpenERP/Odoo will call name_get on your model to display this. If you override name_get you can return whatever you want, otherwise it will use the name_get on the BaseModel class.
This will:
Return the field specied by you as _rec_name on your model
Look for a column called "name" and use that.
Auto-generate one.
The easiest thing to do as Quentin said is have a column called "name" but sometimes it doesn't make sense. For example, in product.supplierinfo the name field is actually the supplier ID - seems like someone was too lazy to do it properly.
Failing that, define a _rec_name field or override name_get yourself but there are a couple of got-chas.
Unlike functional fields, name_get returns a list of tuples where each tuple is (id, name).
If you use a column other than name or you override name_get, you also need to think about overriding name_search to give the user a consistent behaviour. The product.product model has good examples of this.