Django admin custom form in create,update,view based on parent-child table relation - django-admin

I have one table called product and it is having field category based on category i will have to save relevant information in correct category table
table like below
class Product(models.Model):
id = models.CharField(primary_key=True, max_length=36)
name = models.CharField(max_length=255)
code = models.CharField(unique=True, max_length=31)
category = models.ForeignKey('ProductCategory', models.DO_NOTHING, db_column='category')
class CategoryOneProduct(models.Model):
id = models.CharField(primary_key=True, max_length=36)
product = models.OneToOneField('Product', models.DO_NOTHING, unique=True, blank=True, null=True)
traffic_code = models.IntegerField()
routing = models.IntegerField(blank=True, null=True)
i want to build admin UI which will display field from category table based on category and same thing i will have to achieve in create ,update , display
is it possible to do it ?

Finally after lots of searching i found Stackedinline and tabularinline facility provided by Django which is giving above ability to show the required data

Related

Getting different product id for different categories

I am trying to add a link on my website's product pages and redirect the users based on the category that the product belongs to. For example, I have a category chairs which is having a Category Id of 39 and I am having another category desks for which the category id is 52.
Now my issue with the above scenario is when I am moving into the product page through category pages I am getting the above-mentioned category Id's properly and the URL will be
http://example.com/chairs/wood-chair.html
but when I am trying to search for the product directly from the search box and move into the product page from there the URL becomes
http://example.com/wood-chair.html
the category id becomes 2 and this happens with every category and it shows the category name as default category when I go to the product page through search box. How can I resolve this? kindly let me know if there is any parameter that doesn't change on the product page which can enable me to display the content based on the category the product belongs to.
You can force magento to set a category with adding an observer on catalog_controller_product_view:
class My_Module_Model_Observer extends Mage_Core_Model_Observer
{
public function addCategoryToBreadcrumbs(Varien_Event_Observer $observer)
{
if (Mage::registry('current_category')) {
return;
}
$product = $observer->getProduct();
$product->setDoNotUseCategoryId(false);
$categoryIds = $product->getCategoryIds();
if (count($categoryIds)) {
$categories = Mage::getModel('catalog/category')->getCollection()
->addAttributeToFilter('entity_id', $categoryIds)
->addAttributeToFilter('is_active', 1);
$categories->getSelect()->order('level DESC')->limit(1);
Mage::register('current_category', $categories->getFirstItem());
}
}
}
Full code here: https://magento.stackexchange.com/questions/178268/add-category-path-to-breadcrumbs-on-product-view-page/178592#178592

Different queryset optimisation for list view and change view in Django Admin

The get_queryset method for an admin model can be overridden; I use it to select/prefetch objects that are OneToOneFields or ManyToManyFields. However, the list view for my model shows only concise information while the change view contains many more objects. It would not make sense to prefetch ManyToManyField relations in the list view if these will not be displayed anyway.
Sample model:
class Location(TimeStampedModel):
owner = models.ForeignKey('Profile', on_delete=models.CASCADE)
postcode = models.CharField("postcode", max_length=11, blank=True)
tenants = models.ManyToManyField('Profile', blank=True)
Sample admin model:
#admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
list_display = ('owner', 'postcode')
fields = ('owner', 'postcode', 'tenants')
filter_horizontal = ('tenants',)
def get_queryset(self, request):
qs = super(LocationAdmin, self).get_queryset(request).select_related('owner__user')
qs = qs.prefetch_related('tenants')
return qs
Is it possible to define different optimisations for the queryset returned for the list view of the model and the queryset returned for the change/add view of the same model?
That is, in the sample admin model above, the qs.prefetch_related('tenants') line will be relevant for the change/add view only?
The easiest way to achieve this is to use the request.resolver_match attribute which can be used to work out which view you are executing. The following is slightly hacky/fragile (it is essentially using some internals), but works:
class LocationAdmin(admin.ModelAdmin):
list_display = ['owner', 'postcode']
fields = ['owner', 'postcode', 'tenants']
filter_horizontal = ['tenants']
def get_queryset(self, request):
qs = super(LocationAdmin, self).get_queryset(request)
qs = qs.select_related('owner__user')
if request.resolver_match.func.__name__ == 'change_view':
qs = qs.prefetch_related('tenants')
return qs
You should also consider whether you need this and whether it will actually work. The change view shows only one main object, which means that the N+1 problem for a list of objects often does not apply. In addition, the queries for inlines and the widgets for foreign key and many-to-many fields may not use the querysets you provide from get_queryset. For this case, testing with Django 1.10.2, the prefetch_related call did not reduce the number of queries the 'change' view executed. The 'add' view did not use the get_queryset method at all.
See complete demo app at https://github.com/spookylukey/djangoadmintips/tree/master/queryset_optimization

iOS: Magical Record import hierarchical relationship

I have a hierarchically-structured data representing categories, where a category has a parent category and a list of children categories.
This is being retrieved from a web service with a JSON in this form:
{
id = 1;
name = MyCategoryName;
parentId = 328;
}
I have set up my Data Model as follows:
On the identifierattribute I have set mappedKeyName = id
On the children relationship I have set relatedByAttribute = identifier
On the parent relationship I have set mappedKeyName = parentId and relatedByAttribute = identifier
When I am using [MR_importFromObject:inContext:] the database contains empty rows which I believe is because MR cannot find the parent category to be set.
What am I doing wrong in the data model ? Is there any way this can be achieved using only the import functionality of Magical Record or I have to manually establish the relationship after all categories have been saved to the database ?

How do you add multiple Objects to an Object Attribute in Groovy? --- In Bootstrap.groovy

Making a simple purchase order application in Grails, where I have Category (eg: TV, Video...), Brand, and Item. A Brand is associated (hasMany) categories, for example Sony makes Video and TV's.
Inside Bootstrap.groovy, I want to do the following:
Brand jvc = new Brand(name:"JVC")
Brand sony = new Brand(name:"Sony")
Brand samsung = new Brand(name:"Samsung")
Category tv = new Category(name:"Television")
Category video = new Category(name:"Video")
Category laptop = new Category(name:"Laptop")
sony.categories.(tv) ----> These methods are wrong
sony.addCategory(video) ----> These methods are wrong
sony.addCategory(laptop)
How do I associate the brand with multiple categories? Notice I tried many different method templates and neither worked. The attribute in the Brand class is static hasMany [categories:Category].
When you have static hasMany = [categories:Category] this adds a Set named categories to your class and adds a dynamic method addToCategories which does what you want. It initializes the set if it's null (will be the case for new instances), then adds the instance to the Set, and if it's bidirectional it sets the back-reference. So those last three lines should be
sony.addToCategories(tv)
sony.addToCategories(video)
sony.addToCategories(laptop)
This is described in the user guide and every book on Grails since it's a very fundamental feature of mapping collections.

Why is django admin not accepting Nullable foreign keys?

Here is a simplified version of one of my models:
class ImportRule(models.Model):
feed = models.ForeignKey(Feed)
name = models.CharField(max_length=255)
feed_provider_category = models.ForeignKey(FeedProviderCategory, null=True)
target_subcategories = models.ManyToManyField(Subcategory)
This class manages a rule for importing a list of items from a feed into the database.
The admin system won't let me add an ImportRule without selecting a feed_provider_category despite it being declared in the model as nullable. The database (SQLite at the moment) even checks out ok:
>>> .schema
...
CREATE TABLE "someapp_importrule" (
"id" integer NOT NULL PRIMARY KEY,
"feed_id" integer NOT NULL REFERENCES "someapp_feed" ("id"),
"name" varchar(255) NOT NULL,
"feed_provider_category_id" integer REFERENCES "someapp_feedprovidercategory" ("id"),
);
...
I can create the object in the python shell easily enough:
f = Feed.objects.get(pk=1)
i = ImportRule(name='test', feed=f)
i.save()
...but the admin system won't let me edit it, of course.
How can I get the admin to let me edit/create objects without specifying that foreign key?
How about blank=True? From Django's docs:
If True, the field is allowed to be blank. Default is False.
You should try adding null=True, like this one:
car = models.ForeignKey(Car, default=None, null=True, blank=True)
...ok, I found out how to do this on my own. It might not be the best way, but I created a custom Form to validate the model:
class AdminImportRuleForm(forms.ModelForm):
class Meta:
model = ImportRule
name = forms.CharField(max_length=255)
feed = forms.ModelChoiceField(required=True, queryset=Feed.objects.all())
feed_provider_category = forms.ModelChoiceField(required=False, queryset=FeedProviderCategory.objects.all())
target_subcategories = forms.ModelMultipleChoiceField(queryset=Subcategory.objects.all())
And I linked it into the Admin class:
class ImportRuleAdmin(admin.ModelAdmin):
form = AdminImportRuleForm
...
This took a lot of working out and a lot of unnecessary bother, so if anyone else has a better solution they get vote-ups/accepts/whatever it will let me give :)

Resources