By default, a Django model field is set based on another model field

I am using Django Admin to create a management site. There are two tables, one is ModelA with the data in it, the other is ModelB , in which there is nothing. If one field of the model b_b in ModelB is None, it can be displayed on the web page with the value of the ModelA a_b field.

I do not know how to do that. Here is the pseudo code:

In models.py

 from django.db import models class ModelA(models.Model): a_a = models.CharField(max_length=6) a_b = models.CharField(max_length=6) class ModelB(models.Model): modela = models.OneToOneField(ModelA) b_b = models.CharField(max_length=6, choices=[(1, 'M'), (2, 'F')], default=self.modela.a_b) 

In admin.py

 from django.contrib import admin from .models import ModelA, ModelB class ModelBAdmin(admin.ModelAdmin): fields = ['b_b'] list_display = ('b_b') 

I think that if b_b modelB has a default value for the relative a_b value for model A, I have the default value b_b (View) on the django administration change page (admin), which binds the data to a specific instance of modelB.

I want to fill in b_b on the webpage more easily.

I do not know if this requirement can be achieved? Or is there another way to achieve this?

I am trying to configure a template filter as follows:

In the /admin/includes/fieldset.html templates

  {% load drop_null %} {% if field.is_checkbox %} {{ field.field }}{{ field.label_tag }} {% else %} {{ field.label_tag }} {% if field.is_readonly %} <p>{{ field.contents }}</p> {% else %} {% if field.field.name == 'b_b' %} {{ field|dropnull }} {% else %} {{ field.field }} {% endif %} {% endif %} {% endif %} 

In templatetags / drop_null.py

 from django import template register = template.Library() @register.filter(name='dropnull') def dropnull(cls): return cls.modela.a_b 

Field '<django.contrib.admin.helpers.AdminField Object at 0x3cc3550>. This is not an example of ModelB. How can I get an instance of ModelB?

+5
source share
2 answers

You can override the save method of your modelB model instead of providing a default value:

 class ModelB(models.Model): modela = models.OneToOneField(ModelA) b_b = models.CharField(max_length=6, choices=[(1, 'M'), (2, 'F')], blank=True) def save(self, *args, **kwargs): if not self.b_b: self.b_b = self.modela.a_b super(ModelB, self).save(*args, **kwargs) 

Edit after clarification in comments

If you just want to display the value for visitors, but want to keep the fact that ModelB.b_b empty, the logic should be in the template.

Assuming your set of objB in context is a modelB object that you are interested in displaying, the corresponding part of the template should look like this:

 {% with objB.b_b as bValue %} {% if not bValue %} <p>{{ objB.modela.a_b }}</p> {% else %} <p>{{ bValue }}</p> {% endif %} {% endwith %} 
+1
source

You can define and register one user-defined template filter for admin templates.

From the documentation: https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/

0
source

All Articles