is it possible to issue a get result, only with certain fields in models, and not all? where fields must be defined inside models, like def or mixin. something like clean_data if a method is requested
view
cls = Class.objects.get(related_uuid='xxx')
you only need to display device and related_uuid, but define this in models.py itself, not in views.py
models
class Orders(models.Model):
device = models.CharField(max_length=150)
serial = models.CharField(max_length=150, blank=True)
related_uuid = models.CharField(max_length=22, blank=True)
Related
I am trying to create form using this model. I want to add data in this database model using form to perform CRUD operation. I am using MySQL database.
models.py
from django.db import models
from .managers import CategoryManager, SubCategoryManager
# this is my parent model
class Node(models.Model):
name = models.CharField(max_length=150)
parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
related_name='children',
null=True,
blank=True
)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
verbose_name_plural = 'Nodes'
class Category(Node):
object = CategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'Categories'
class SubCategory(Node):
object = SubCategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'SubCategories'
class Product(models.Model):
sub_category = models.ForeignKey(
SubCategory, on_delete=models.CASCADE
)
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
def __str__(self):
return self.name
Try the Imagine smart compiler which allows automatic generating of code + tests for your CRUD APIs and Django models from a very simple config. Amongst other things, it generates code in the correct way to handle foreign key relationships in Django Views. You can also try a demo here imagine.ai/demo
PS: Something like this simple config will generate all the code for the CRUD API along with the tests!
Model Node {
id integer [primary-key]
name string [max-length 150]
}
Model Product {
id integer [primary-key]
name string [max-length 100]
description string [nullable]
}
I have a base model and 2 child models inheriting from base model
class Module(models.Model):
name = models.CharField(max_length=200, null=False)
def __str__(self):
return self.name
class A(Module):
title = models.CharField(max_length=300, null=False, verbose_name='Title')
image = models.FileField(upload_to='uploads/', null=True)
class B(Module):
title = models.CharField(max_length=300, null=False, verbose_name='Title')
sub_title = models.CharField(max_length=300, null=False, verbose_name='Title')
image = models.FileField(upload_to='uploads/', null=True)
This is working fine, Django creates table inside child model table that references to parent.
Now, where I struggle is that there is an additional app with its own model that needs to query related parent model with its all child models. Lets assume this is my app referencing to module class
class Page(models.Model):
title = models.CharField(max_length=300, null=False)
slug = models.SlugField(max_length=300, null=False, db_index = True)
modules = models.ManyToManyField('modules.module')
By this current setup, Django stores parent model id in child model table, I'm not using django on client side hence in my sql query I'd like to get the child module attached to parent, by having a reference to what child model is referencing to. Please have in mind, Parent is linked to only one model.
I've looked at abstract, proxy models as well as model_utils.managers InheritenceManager but none stored child model information in parent.
How do I achieve that?
Thanks
The relationship is already defined by the ManyToManyField. Being able to display it is perhaps the question you're getting at.
You can reference the "through" model and register it in Admin like so:
from django.contrib import admin
# https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#inlinemodeladmin-objects
#
# You can use TabularInline, or StackedInline --- whichever meets your style preferences
#
class PageModuleInline(admin.TabularInline):
model = Page.modules.through # the implicit "join table" model
class PageAdmin(admin.ModelAdmin):
inlines = [
PageModuleInline,
]
class ModuleAdmin(admin.ModelAdmin):
inlines = [
PageModuleInline,
]
see: https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#working-with-many-to-many-models
I have 2 models that look like this:
models.py
class Client(models.Model):
deal = models.ManyToManyField('Deal', related_name="clients")
class Deal(models.Model):
client = models.ManyToManyField(Client, related_name="deals")
Then in the admin, I have inlined the related models to make it easy to make changes regardless of the object type you have open.
admin.py
class ClientInline(admin.TabularInline):
model = Deal.client.through
class DealAdmin(admin.ModelAdmin):
inlines = [ClientInline]
class DealInline(admin.TabularInline):
model = Client.deal.through
class ClientAdmin(admin.ModelAdmin):
inlines = [DealInline]
However, if you add a Client to a Deal and then open the Client detail page, the corresponding deal does not appear. Is there something I'm not connecting?
It is enough to have relation define only in one model. Otherwise you'll have 2 separate tables for separate ManyToMany relation: ClientDeal and DealClient.
What you need to do is to choose which one you need to leave. And probably update Admin inlines according to Django Admin documentation
class Client(models.Model):
deals = models.ManyToManyField('Deal', related_name="clients")
class Deal(models.Model):
pass
Yes, If you're using models.manytoMany() , you have to put it only in one model. no the two
But there's a very good attribute you should use: through
with through attribute you can create a intermediate model. here there's an example:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=200)
groups = models.ManyToManyField('Group', through='GroupMember', related_name='people')
class Meta:
ordering = ['name']
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=200)
class Meta:
ordering = ['name']
def __unicode__(self):
return self.name
class GroupMember(models.Model):
person = models.ForeignKey(Person, related_name='membership')
group = models.ForeignKey(Group, related_name='membership')
type = models.CharField(max_length=100)
def __unicode__(self):
return "%s is in group %s (as %s)" % (self.person, self.group, self.type))
later, you can use your inline admin class!
I just tested this an you were actually really close.
First, #wowkin2 said, you don't want to define a ManyToManyField in both models so I would probably just define it in your Deal model.
Second, replace this:
class DealInline(admin.TabularInline):
model = Client.deal.through
with this:
class DealInline(admin.TabularInline):
model = Deal.client.through
And everything should work.
So, this is what your files should now look like:
models.py
class Deal(models.Model):
client = models.ManyToManyField(Client, related_name="deals")
admin.py
class ClientInline(admin.TabularInline):
model = Deal.client.through
class DealAdmin(admin.ModelAdmin):
inlines = [ClientInline]
class DealInline(admin.TabularInline):
model = Deal.client.through
class ClientAdmin(admin.ModelAdmin):
inlines = [DealInline]
I have a model with an attribute that is connected to another model as follow:
class Book(models.Model):
synced = models.OneToOneField('SyncedBook'
related_name='internal',
on_delete=models.CASCADE)
# some more attributes here...
#property
def book_address(self)
return self.synced.book_address
However, the book_address is a also a FK in the SyncedBook table as follow:
book_address = models.ForeignKey('Address', db_index=True, null=True, blank=True,
related_name='address_book', on_delete=models.PROTECT)
I don't know and understand how to be able to edit the book_address through the Django admin page in class BookingAdmin(admin.ModelAdmin), even though I have read over the documentation. At first I have the attribute as readonly, but now I want to be able to edit it and save the new address from the Address table. Is there a way to make it happen through the class BookingAdmin(admin.ModelAdmin) and how? Any example and solution would be appreciate
Model properties are typically used for presenting logically defined data for a particular model instance and not necessarily storing data on the model instance itself.
An example of when to use a model property is as follows:
# Defines a product instance
class Product(model.Models):
name = models.CharField(max_length=100)
description = models.TextField()
active = models.BooleanField(default=True)
cost = models.DecimalField(max_digits=5, decimal_places=2)
price = models.DecimalField(max_digits=5, decimal_places=2)
# calculate profits on product
#property
def profit(self)
p = self.price - self.cost
return p
In your case, you are trying to actually be able to modify data against a related model instance within the django admin. To me this sounds like more specifically an Inline (click here for documentation)
So in your case, you would need to create something like the following to your admin.py file:
class SyncedBookInline(admin.TabularInline):
model = BookInline
#admin.Register(Book)
class BookAdmin(admin.ModelAdmin):
# all your model admin settings
inlines = [SyncedBookInline]
Additional Info:
The Inline solution should still work for you. Please see the working code listed below:
models.py:
from django.db import models
class Hero(models.Model):
name = models.CharField(max_length=50)
class HeroAcquaintance(models.Model):
name = models.CharField(max_length=50)
hero = models.OneToOneField(Hero, on_delete=models.CASCADE)
admin.py:
from django.contrib import admin
from .models import *
class HeroAcquaintanceInline(admin.TabularInline):
model = HeroAcquaintance
#admin.register(Hero)
class HeroAdmin(admin.ModelAdmin):
list_display = (
'name',
)
inlines = [HeroAcquaintanceInline]
#admin.register(HeroAcquaintance)
class HeroAcquaintanceAdmin(admin.ModelAdmin):
list_display = (
'name',
)
Screenshot:
I'm having trouble overriding the formset on a TabularInline inline of a ModelAdmin object in my admin site. I know you're supposed to have a model associated with a TabularInline object, but I'm not sure how to specify this on the form object used to generate the formset. With the code below, I'm getting "'AppAssetInline.formset' does not inherit from BaseModelFormSet."
class AppAssetForm(forms.ModelForm):
model = App.assets.through
primary = forms.BooleanField()
uuid = forms.CharField()
class AppAssetInline(admin.TabularInline):
model = App.assets.through
AssetFormset = formset_factory(AppAssetForm)
formset = AssetFormset
class AppAdmin(admin.ModelAdmin):
inlines = [AppAssetInline,]
The answer to my question didn't have to do with how I was structuring my forms, but rather how I was joining fields on my models. I had the following structure in my models:
class App(models.Model):
package = models.FileField(upload_to=settings.APP_PACKAGE_ROOT)
assets = models.ManyToManyField('AppAsset', blank=True, null=True)
download_count = models.IntegerField(default=0)
class AppAsset(models.Model):
def __unicode__(self):
return self.asset_file.name
notes = models.CharField(max_length=255, null=True, blank=True)
type = models.CharField(max_length=255, null=True, blank=True)
asset_file = models.FileField(upload_to=settings.APP_PACKAGE_ROOT)
What I did was change the structure such that AppAsset now has a foreign key on App for its assets. After that, I could use the TabularInline on the AppAsset model with no problems. Here are the latest source files:
https://github.com/ridecharge/spout/blob/master/Spout/AppDistribution/models.py
https://github.com/ridecharge/spout/blob/master/Spout/AppDistribution/admin.py
You should use django.forms.models.inlineformset_factory instead of formset_factory