如何将字段模型的默认值设置为另一个模型字段



这里是models.py文件

class album(TimeStampedModel):
#album_artist = models.ForeignKey(artist, on_delete=models.CASCADE)
album_name = models.CharField(max_length=100, default="New Album")
#released_at = models.DateTimeField(blank=False, null=False)
#price = models.DecimalField(
#   max_digits=6, decimal_places=2, blank=False, null=False)
#is_approved = models.BooleanField(
#   default=False, blank=False)
#def __str__(self):
#    return self.album_name

class song(models.Model):
name = models.CharField(max_length=100,blank=True,null=False)
album = models.ForeignKey(album, on_delete=models.CASCADE,default=None)
# image = models.ImageField(upload_to='images/', blank = False)
# thumb = ProcessedImageField(upload_to = 'thumbs/', format='JPEG')
# audio = models.FileField(
# upload_to='audios/', validators=[FileExtensionValidator(['mp3', 'wav'])])
# def __str__(self):
# return self.name

我想让歌曲名称的默认值等于我通过专辑Foreignkey选择的专辑名称。(在管理面板页面中(有什么帮助吗?

如果歌曲名称设置为blank=True。您可以创建一个pre_save信号来设置名称。

...
from django.db.models.signals import pre_save
from django.dispatch import receiver
....
@receiver(pre_save, sender=Song)
def song_pre_save(sender, instance, **kwargs):
if instance.name is None:
album = Album.object.get(pk=instance.album)
instance.name = album.album_name

你可以在Django网站上阅读更多

因为您是album模型的__str__方法只是self.name,所以这是可能的(否则选项文本将不正确(。。您必须覆盖Song的Admin change_form模板

您需要在此路径中创建文件change_form.html,创建所有文件夹:templates/admin/{app_name}/song/change_form.html

  • {app_name}=Song的model.py所在的文件夹名称

change_form.html

  • 您不能仅覆盖add_form.html,所以我添加了一个if-so,如果它已经有值(对于实际的变更表单(,它将跳过该字段
{% extends "admin/change_form.html" %}
{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
<script>
django.jQuery(function($) { // Use Django's included Jquery
// Default form format `id_{fieldname}`
$('#id_album').change(function(){
if ($('#id_name').val() == ''){
// $(this).val() would be pk, so we need to find the selected option and use it's text
$('#id_name').val($(this).find('option:selected').text());
};
});
});
</script>
{% endblock %}

我不确定应该覆盖哪个Block,所以我选择了extrahead。。也许还有更好的,但这是唯一一个突然出现在我面前并有意义的