0

I have models as Offer , Wood , SliceTec and JointTec. And Wood related with SliceTec and JointTec by M2M field. At Django admin I can select multiple options for SliceTec and JointTec when adding new Wood record. No problem. When it comes to Offer I need to show options from selected Wood records woodSlice data and also woodJoint data.

For ex;

SliceTec data: Slicet A, Slicet B, Slicet C

JointTec data: Jointt A, Jointt B, Jointt C

Wood data: Wood A , (Slicet A, Slicet C), (Jointt B, Jointt C)

At Offer I need to show Slicet A and Slicet B options when Wood A selected.

class Offer(models.Model):
    name            = models.CharField(max_length=200, verbose_name='Adınız Soyadınız')
    phone           = models.BigIntegerField(verbose_name='Telefon Numaranız')
    email           = models.EmailField(verbose_name='E-mail Adresiniz')
    date            = models.DateTimeField(verbose_name='Teklif Tarihi')
    frontWood       = models.ForeignKey('Wood', on_delete=models.PROTECT)
    frontSlice      = models.CharField(max_length=200)
    frontJoint      = models.CharField(max_length=200)
    frontSupport    = models.ForeignKey('Support', on_delete=models.PROTECT)
    frontThick      = models.CharField(max_length=200)
    frontDimen      = models.CharField(max_length=200)
    frontFlow       = models.ForeignKey('Flow', on_delete=models.PROTECT)
    frontGlue       = models.ForeignKey('Glue', on_delete=models.PROTECT)
    class Meta:
        verbose_name        = 'Teklif Talebi'
        verbose_name_plural = 'Teklif Talepleri'
    def __str__(self):
        return self.name

class Wood(models.Model):
    woodName    = models.CharField(max_length=200, verbose_name='Ahşap Adı')
    woodCode    = models.CharField(max_length=50, verbose_name='Stok Kodu', blank=True, null=True)
    woodSlice   = models.ManyToManyField('SliceTec', verbose_name='Uygun Kesim Teknikleri')
    woodJoint   = models.ManyToManyField('JointTec', verbose_name='Uygun Ekleme Teknikleri')
    woodImage   = models.ImageField(verbose_name='Görsel', blank=True, null=True)
    woodPrice   = models.PositiveIntegerField(verbose_name='Fiyat Düzeyi', blank=True, null=True)
    woodDesc    = models.TextField(verbose_name='Açıklama', blank=True, null=True)
    class Meta:
        verbose_name        = 'Ahşap Türü'
        verbose_name_plural = 'Ahşap Türleri'
    def __str__(self):
        return self.woodName

class SliceTec(models.Model):
    sliceName   = models.CharField(max_length=200, verbose_name='Kesim Tekniği Adı')
    sliceImage  = models.ImageField(verbose_name='Görsel', blank=True, null=True)
    sliceDesc   = models.TextField(verbose_name='Açıklama', blank=True, null=True)
    class Meta:
        verbose_name        = 'Kesim Tekniği'
        verbose_name_plural = 'Kesim Teknikleri'
    def __str__(self):
            return self.sliceName

class JointTec(models.Model):
    jointName   = models.CharField(max_length=200, verbose_name='Ekleme Tekniği Adı')
    jointImage  = models.ImageField(verbose_name='Görsel', blank=True, null=True)
    jointDesc   = models.TextField(verbose_name='Açıklama', blank=True, null=True)
    class Meta:
        verbose_name        = 'Ekleme Tekniği'
        verbose_name_plural = 'Ekleme Teknikleri'
    def __str__(self):
            return self.jointName

2 Answers2

0

If you are making single form, then, unless I'm missing something, there is no way to do this, since you don't know which wood is selected when you render the form.

You can try to implement logic inside the page using javascript

eran
  • 6,731
  • 6
  • 35
  • 52
0

You can change the labels in the admin with the following code.

Add this to your Wood model:

def description(self):
    slice_names = ','.join(self.woodSlice.values_list('sliceName', flat=True))
    joint_names = ','.join(self.woodJoint.values_list('jointName', flat=True))
    return '{}, (), ()'.format(self.woodName, slice_names, joint_names)

Then in the admin you can override the ComponentForm of your OfferAdmin

class OfferComponentForm(forms.ModelForm):
    class Meta:
        model = Offer
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(OfferComponentForm, self).__init__(*args, **kwargs)

        id_dict = Wood.objects.in_bulk()
        current_choices = self.fields['frontWood'].choices
        new_choices = [(value, id_dict[value].description()) for value, label in current_choices]
        self.fields['frontWood'].choices = new_choices

@admin.register(Offer)
class OfferAdmin
    form = OfferComponentForm
    model = Offer
Jura Brazdil
  • 970
  • 7
  • 15
  • Got error; Exception Type: AttributeError Exception Value: 'str' object has no attribute 'description' Exception Location: C:\Users\egula\Desktop\ilkprojeler\okumalistesi\panelbuilder\admin.py in , line 22 – Emre Gülas May 03 '19 at 19:29
  • Of course, I am sorry. Value is only a reference to a Wood object. I fixed the code by adding an `id_dict` that holds pairs {wood_id (int): wood_object (Wood)} and calling the description through that. `description` was also missing the brackets which I added – Jura Brazdil May 04 '19 at 14:01