How to get the current App name in models.py in Django? - python

I have a app called C3po. I'm working on the model "Article". In this model I want to create a ForeignKey field with a custom related_name to a model in another app called Lea. To make sure the related_name is unique, I want to name it "c3po_articles". But I don't want to hard code the app name c3po. How can I get the folder / app name in a dynamic way ? Do I use __file__ and split it or is there a more elegant method ?
Thank you for your help :)

The related_name attribute supports automatic string interpolation with two variables: app_label and class. For example:
models.ForeignKey(FooModel, related_name='%(app_label)s_%(class)s_foo')
Now, I'm honestly not sure if Django will let you just include one or the other, i.e. just '%(app_label)s_foo', but you can try. (After a closer look at the docs, I highly doubt it. It seems like it's both or neither, but still, test it yourself and see.)
See: https://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name
EDIT
Actually, after thinking about it more, for your case, you could just use '%(app_label)s_%(class)ss', which should net you c3po_articles as the related_name.

Related

How to use apps with the same name in django

I created a project say foo. And created an app named admin. But it causes an error
django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: admin”
So I read this and made changes as mentioned there. I marked the label as foo.admin.
I don't exactly know what the label is, but maybe this is the unique name given to an app to distinguish apps with the same name in case.
So is that mean, everywhere I have to use label instead of name?
But it causes another error.
String model references must be of the form 'app_label.ModelName'.
So I used the name in models as foo.admin in ForeignKey parameter. But the same error comes up. But the error persists.
I googled the error and found this. So I changed the ForeignKey parameter from foo.admin to admin. But in either case, I'm having this error.
So in short I want to ask
How to use apps with the same name in the same django project, like Which files are need to be modified and what to write ForeignKey parameters etc.?
(I'm using django 2.0)

django test model field

i'm currently writing tests for my django project and i need to make sure
that a specific field of a model is of a certain type.
for example in model Pictures i want to make sure that there is a field with the
name "image" and that he of type ImageField.
i also want to be able to check if an attribute is of type ForeignKey of
model Pictures.
i tried to use the assertIsInstance, but i need to assign the attribute or else
he is None.
does someone know how to do it?
To answer your question, a check like this should work:
from django.db.models import ImageField
from wherever.mymodels import Pictures
...
field = Pictures._meta.get_field("image")
assertTrue(isinstance(field, ImageField))
Though, for my 2¢, it may make more sense for your unit test to check that setting the "image" of some Picture instance works as-expected, rather than just checking for an ImageField named "image". After all, what you should really be checking with a test case is: "will the code I'm using to upload/validate/save images reliably work"?

Django haystack. How to alter names of check boxes?

I installed django haystack using whoosh. Everything works great, but I want to alter the names displayed next to the check boxes. I know they are generated using the verbose name set up on the models but I still have an issue with the 's' being added at the end of the names. I know there are custom forms and custom views but I am new to programming and some of the concepts do not make sense. I have also tried to search for any ideas but have had no luck. Any suggestions/advice?
Thanks in advance!
:)
is it not the label=_("Field_name") parameter in the checkbox field?
if its about the verbose name there is also verbose_name_plural which can be set up in models

Specifying model Meta data through decorators (django)

The problem: I wish to use Postgres Schemas to separate the tables of different parts of my django app at database level.
Aside
You can skip this section, but I think it's helpful to add context to these things. My app is working on a database of existing data (stored in the public schema, helpfully), which it's very important I don't modify. As such, I want to separate "my" data into a separate schema (to which django will be given read/write/play in the sand access), while restricting access to the public schema to read-only. I originally tried to solve this by separating my data out into a separate database and using database routing, but it turns out (if I'd only read the documentation) that django doesn't support cross database dependencies (which is fair enough I suppose), and my models have foreign keys into the read-only data.
The meat
There exists a workaround for Django's lack of schema support (which you can read about here) which is to specify the db_table attribute in your model's meta, like so:
class MyModel(models.Model):
attribute1 = models.CharField()
#Fool django into using the schema
class Meta:
db_table = 'schema_name\".\"table_name'
This is great, but I didn't really want to have to write this for every single model in my app - for a start, it doesn't seem pythonic, and also there's every chance of me forgetting when I have to add a new model.
My solution was the following snippet:
def SchemaBasedModel(cls):
class Meta:
db_table = '%s\".\"%s' % (schema_name, cls.__name__)
cls.Meta = Meta
return cls
#SchemaBasedModel
class MyModel(models.Model):
attribute1 = models.CharField()
...
When I then run python manage.py shell I get the following:
>>> from myapp import models
>>> myModel = models.MyModel
>>> myModel.Meta.db_table
'myschema"."mymodel'
>>>
"Looks good to me," I thought. I then ran: python manage.py sqlall myapp. Sadly, this yielded the original table names - that is, the table names as they were before I applied this meta info. When I went back and applied the meta info "by hand" (i.e. by adding Meta inner classes to all my models), things were as expected (new table names).
I was hoping somebody could enlighten me as to what was going on here? Or, more usefully, what's the "right" way to do this? I thought the decorator pattern I've talked about here would be just the ticket for this problem, but apparently it's a non-starter. How can I quickly and easily apply this meta info to all my models, without typing it out every single time?
Edit: Perhaps I was a little unclear when I asked this - I'm as interested in know what's "actually going on" (i.e. why things aren't working the way I thought they would - what did I misunderstand here?) as how to solve my problem (clear separation of "my" data from legacy data, preferably on a schema level - but it's not the end of the world if I have to dump everything into the public schema and manage permissions on a per-table basis).
Second Edit: The accepted answer doesn't necessarily tell me what I really want to know, but it is probably the right solution for the actual problem. Short answer: don't do this.
I didn't really want to have to write this for every single model in my app -
for a start, it doesn't seem pythonic,
That's false. Some things have to be written down explicitly. "Explicit is better than Implicit".
and also there's every chance of me forgetting when I have to add a new model
That's false, also.
You won't "forget".
Bottom Line: Don't mess with this kind of thing. Simply include the 2 lines of code explicitly where necessary.
You don't have that many tables.
You won't forget.
Also, be sure to use DB permissions. Grant SELECT permission only on your "legacy" tables (the tables you don't want to write to). Then you can't write to them.

Python/Django application with dynamic model name (application reuse)

excuse me in advance if this is not the right title for the problem but here it is:
You have application that works with pre defined model. What happens if you want to
use this application one more time in your project but pointing to different model (same structure but differen name).
For example - you have a "News" application that is fully working but you want to have also and articles the do the same job but you want it in different table.
I'm pretty sure that copying the whole application and renaming the Model isn`t the "pythonic" way so if someone knows how this is done please share your knowledge.
thanks in advance,
Ilian Iliev
This is what abstract models are for. Define once, and all children will acquire the fields in the abstract model, plus be able to define additional fields.

Categories