I am trying to export all my database with a prefetch_related but I only get data from the main model.
My models:
class GvtCompoModel(models.Model):
gvtCompo= models.CharField(max_length=1000, blank=False, null=False)
...
class ActsIdsModel(models.Model):
year = models.IntegerField(max_length=4, blank=False, null=False)
...
class RespProposModel(models.Model):
respPropos=models.CharField(max_length=50, unique=True)
nationResp = models.ForeignKey('NationRespModel', blank=True, null=True, default=None)
nationalPartyResp = models.ForeignKey('NationalPartyRespModel', blank=True, null=True, default=None)
euGroupResp = models.ForeignKey('EUGroupRespModel', blank=True, null=True, default=None)
class ActsInfoModel(models.Model):
#id of the act
actId = models.OneToOneField(ActsIdsModel, primary_key=True)
respProposId1=models.ForeignKey('RespProposModel', related_name='respProposId1', blank=True, null=True, default=None)
respProposId2=models.ForeignKey('RespProposModel', related_name='respProposId2', blank=True, null=True, default=None)
respProposId3=models.ForeignKey('RespProposModel', related_name='respProposId3', blank=True, null=True, default=None)
gvtCompo= models.ManyToManyField(GvtCompoModel)
My view:
dumpDB=ActsInfoModel.objects.all().prefetch_related("actId", "respProposId1", "respProposId2", "respProposId3", "gvtCompo")
for act in dumpDB.values():
for field in act:
print "dumpDB field", field
When I display "field", I see the fields from ActsInfoModel ONLY, the starting model. Is it normal?
You haven't understood the arguments to prefetch_related. It's not a list of fields, but a list of models.
(Note that your field naming convention is also very misleading - respProposId1 and actId are not IDs, but actual instances of the models. Django has created an underlying field in each case by appending _id, so the db columns are respProposId1_id and actId_id. You should just call the fields resp_propos1 and resp_propos2 - also note that normal style is lower_case_with_underscore, not capWords.)
It is normal, that you are seeing fields from ActsInfoModel only. You can access related models via dot notation, like:
acts = ActsInfoModel.objects.all().prefetch_related("actId", "respProposId1", "respProposId2", "respProposId3", "gvtCompo")
for act in acts:
print act.respProposId1.respPropos
Related models are already prefetched, so it won't produce any additional queries. FYI, quote from docs:
Returns a QuerySet that will automatically retrieve, in a single
batch, related objects for each of the specified lookups.
Related
django provide inline formset which allow to 3rd level of nesting, but I need much more complex nesting. It should be fully dynamic, so I can go one to one on each level, but it could be one to many on each level. So far I have this only, but could be expanded for additional sublevels.
class Srts(models.Model):
data = models.CharField(max_length=10, blank=True, null=True)
class Volume(models.Model):
srts = models.ForeignKey('Srts', on_delete=models.CASCADE)
name = models.CharField(max_length=120, blank=True, null=True)
class Qtree(models.Model):
volume = models.ForeignKey('Volume', on_delete=models.CASCADE)
name = models.CharField(max_length=120)
class Server(models.Model):
qtree = models.ForeignKey('Qtree', on_delete=models.CASCADE)
hostname = models.CharField(max_length=120, blank=True, null=True)
class CifsPermission(models.Model):
qtree = models.ForeignKey('Qtree', on_delete=models.CASCADE)
group = models.CharField(max_length=30, blank=True, null=True, default='None')
permission = models.CharField(max_length=30, blank=True, null=True, default='None')
I have been googling a lot last days, but there is not much.
Some examples
django-nested-inline-formsets-example -that basic only 3rd level
Django-better forms -could handle multiple forms on one submit, but not formsets
django-nested-inline -only for admin page
Shoudl be the way to work with not model related form , then do some separation and appropriate logic and then save it to models?
can't add image, some sever error ocured, so giving the link directly
https://imgur.com/a/NQBR6tJ
I would like to to something simular over normal view, not admin view.
I'll shorten the code as simple as possible. Supposedly, we do have two models.
models.py > Products table
CATEGORY = (
('Hard Disk Drive', 'Hard Disk Drive'),
('Solid State Drive', 'Solid State Drive'),
('Graphics Card', 'Graphics Card'),
('Laptop', 'Laptop'),
('RAM', 'RAM'),
('Charger', 'Charger'),
('UPS', 'UPS'),
('Mouse', 'Mouse'),
('Keyboard', 'Keyboard'),
('Motherboard', 'Motherboard'),
('Monitor', 'Monitor'),
('Power Supply', 'Power Supply'),
('Router', 'Router'),
('AVR', 'AVR'),
('Tablet', 'Tablet'),
('System Unit', 'System Unit'),
('Audio Devices', 'Audio Devices'),
('CPU', 'CPU'),
('Others', 'Others'),
)
class Product(models.Model):
model_name = models.CharField(max_length=100, null=True, blank=True)
asset_type = models.CharField(max_length=20, choices=CATEGORY, blank=True)
date = models.DateField(null=True, blank=True)
And the other table > Order table
class Order(models.Model):
product_order = models.ForeignKey(Product, on_delete=models.CASCADE, null=False)
employee = models.ForeignKey(User, models.CASCADE, null=False)
date = models.DateTimeField(auto_now_add=True)
remarks = models.TextField()
And we all know that adding this code will limit the foreignkey choices under the Order form.
limit_choices_to={"asset_type": "Hard Disk Drive"}
limit_choices_to={"asset_type": "Solid State Drive"}
My goal here is to show items from Products table whose asset_type is either "Hard Disk Drive" OR "Solid State Drive". I've read the documentation of Django for "limit_choices_to" and can't see any pertaining to some kind of solution in here. Thank you in advance who knows a way to make this possible.
You can work with the __in lookup [Django-doc] to specify a list of allowed values:
class Order(models.Model):
product_order = models.ForeignKey(
Product,
on_delete=models.CASCADE,
limit_choices_to=dict(asset_type__in=['Hard Disk Drive', 'Solid State Drive'])
)
# …
Note: Specifying null=False [Django-doc] is not necessary: fields are by default not NULLable.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I've got a many-to-many relation from a model called Resource to itself through an intermediary model called RelatedResource:
class Resource(TimeStampedModel):
title = models.CharField(max_length=100, unique=True) # book title, person's name, video title, etc.
description = models.TextField(max_length=500, null=True, blank=True)
link = models.URLField(max_length=500, blank=True, null=True) # dynamically generated for youtube and amazon; todo: uniqueness
resourceID = models.CharField(max_length=20, blank=True, null=True) # todo: uniqueness
picture = models.URLField(max_length=500, blank=True)
tags = TaggableManager()
...
class RelatedResource(models.Model):
input = models.ForeignKey(Resource, related_name="input_resource")
output = models.ForeignKey(Resource, related_name="output_resource")
input_affiliate = models.ForeignKey(Resource, related_name="while_with", blank=True, null=True)
reason = models.CharField(max_length=500)
...
Django complains that having more than 2 foreign keys to Resource is ambiguous, of course, because then it doesn't know which two of the three ForeignKey fields apply in the many-to-many relation.
Is there any way I can keep all 3 ForeignKey fields in the intermediary model and tell Django which 2 are meant for the many-to-many relation?
I think what you are trying to do is recursive relationship.
It is described in here.
https://docs.djangoproject.com/en/1.6/ref/models/fields/#recursive-relationships
And here.
Django recursive relationship
I have an Event model. Events can have many 'presenters'. But each presenter can either 1 of 2 different types of profiles. Profile1 and Profile2. How do I allow both profiles to go into presenters?
This will be 100% backend produced. As to say, admin will be selecting "presenters".
(Don't know if that matters or not).
class Profile1(models.Model):
user = models.ForeignKey(User, null=True, unique=True)
first_name = models.CharField(max_length=20, null=True, blank=True)
last_name = models.CharField(max_length=20, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
about = models.TextField(null=True, blank=True)
tags = models.ManyToManyField(Tag, null=True, blank=True)
country = CountryField()
avatar = models.ImageField(upload_to='avatars/users/', null=True, blank=True)
score = models.FloatField(default=0.0, null=False, blank=True)
organization = models.CharField(max_length=2, choices=organizations)
class Profile2(models.Model):
user = models.ForeignKey(User, null=True, unique=True)
first_name = models.CharField(max_length=20, null=True, blank=True)
last_name = models.CharField(max_length=20, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
about = models.TextField(null=True, blank=True)
tags = models.ManyToManyField(Tag, null=True, blank=True)
country = CountryField()
avatar = models.ImageField(upload_to='avatars/users/', null=True, blank=True)
score = models.FloatField(default=0.0, null=False, blank=True)
...
class Event(models.Model):
title = models.CharField(max_length=200)
sub_heading = models.CharField(max_length=200)
presenters = ManyToManyField(Profile1, Profile2, blank=True, null=True) ?
...
# I've also tried:
profile1_presenters = models.ManyToManyField(Profile1, null=True, blank=True)
profile2_presenters = models.ManyToManyField(Profile2, null=True, blank=True)
# is there a better way to accomplish this?...
I think you have a desing problem here. In my opinion, you must think what is a Presenter and what's the different between a Presenter with "profile 1" and with "profile 2". What are you going to do with this models? Are you sure there are just two profiles? Is there any chance that, in some time from now, a different profile ("profile 3") appears? And profile 4? and profile N?
I recommend you to think again about your models and their relations. Do NOT make this decision thinking of how difficul/easy will be to handle these models from django admin. That's another problem and i'll bet that if you think your models a little bit, this won't be an issue later.
Nevertheless, i can give you some advice of how to acomplish what you want (or i hope so). Once you have think abount how to model these relations, start thinking on how are you going to write your models in django. Here are some questions you will have to answer to yourself:
Do you need one different table (if you are going to use SQL) per profile?
If you cannot answer that, try to answer these:
1) What's the difference between two different profiles?
2) Are there more than one profile?
3) Each presenter have just one profile? What are the chances that this property changes in near future?
I don't know a lot about what you need but i think the best option is to have a model "Profile" apart of your "Presenter" model. May be something like:
class Profile(models.Model):
first_profile_field = ...
second_profile_field = ...
# Each presenter have one profile. One profile can "represent"
# to none or more presenters
class Presenter(models.Model):
first_presenter_field = ....
second_presenter_field = ....
profile = models.ForeignKey(Profile)
class Event(models.Model):
presenters = models.ManyToManyField(Presenter)
....
This is just an idea of how i imagine you could design your model. Here are some links that may help you once you have design your models correctly and have answered the questions i made to you:
https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance
https://docs.djangoproject.com/en/dev/misc/design-philosophies/#models
http://www.martinfowler.com/eaaCatalog/activeRecord.html
And to work with the admin once you decide how your design will be:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/
EDIT:
If i'm not wrong, the only difference between profile 1 and 2 fields is the "organization" field. Am i right? So i recommend you to merge both models since they are almost the same. If they have different methods, or you want to add different managers or whatever, you can use the proxy option of django models. For example, you can do this:
class Profile(models.Model):
#All the fields you listed above, including the "organization" field
class GoldenProfile(models.Model):
#you can define its own managers
objects = GoldenProfileManager()
....
class Meta:
proxy = True
class SilverProfile(models.Model):
....
class Meta:
proxy = True
This way, you can define different methods or the same method with a different behaviour in each model. You can give them their own managers, etcetera.
And the event class should stay like this:
class Event(models.Model):
title = models.CharField(max_length=200)
sub_heading = models.CharField(max_length=200)
presenters = ManyToManyField(Profile, blank=True, null=True)
Hope it helps!
This is are my models i want to relate. i want for collection to appear in the form of occurrence.
class Collection(models.Model):
id = models.AutoField(primary_key=True, null=True)
code = models.CharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=100, null=True, blank=True)
collection_name = models.CharField(max_length=100)
def __unicode__(self):
return self.collection_name
class Meta:
db_table = u'collection'
ordering = ('collection_name',)
class Occurrence(models.Model):
id = models.AutoField(primary_key=True, null=True)
reference = models.IntegerField(null=True, blank=True, editable=False)
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
modified = models.DateTimeField(null=True, blank=True, auto_now=True)
class Meta:
db_table = u'occurrence'
Every time i go to check the Occurrence object i get this error
TemplateSyntaxError at /admin/hotiapp/occurrence/
Caught an exception while rendering: column occurrence.collection_id does not exist
LINE 1: ...LECT "occurrence"."id", "occurrence"."reference", "occurrenc..
And every time i try to add a new occurrence object i get this error
ProgrammingError at /admin/hotiapp/occurrence/add/
column occurrence.collection_id does not exist
LINE 1: SELECT (1) AS "a" FROM "occurrence" WHERE "occurrence"."coll...
What am i doing wrong? or how does ForeignKey works?
The problem is that you have not updated your database table definition since adding the ForeignKey. syncdb doesn't do this for you, as the documentation clearly states. You need to update the SQL manually, or use a tool like South.
Are you sure you mean
collection = models.ForeignKey(Collection, null=True, blank=True, unique=True),
Nullable and Unique? This may not be possible in some databases.
Generally, the unique constraint doesn't seem to make much sense here.
Are you trying to force a 1-to-1 relationship? Use the OneToOneField. http://docs.djangoproject.com/en/1.1/ref/models/fields/#django.db.models.OneToOneField