1

I have a model

class ScrapEventInstructionMap(models.Model):
    instruction = models.ForeignKey(Instruction)
    scrap_code = models.CharField(max_length=100, null=True, blank=True)
    event_code = models.CharField(max_length=100, null=True, blank=True)

    class Meta:
        unique_together = (("instruction", "event_code"), ("instruction", "scrap_code"))

I have used unique_together so that for a particular instruction, scrap_code and event_code should be unique. And from frontend if we're clicking on a particular scrap_code and event_code the instruction page is opening.

I am using InlineModelAdmin in Admin.py so that for one instruction there can be multiple scrap_code or event_code

But issue is like we have two instructions, Instruction 1 and Instruction 2 So if I am entering same scrap_code or event_code in both instructions. It is saving. I have to restrict it in admin page that event_code and scrap_code should also be unique for different instructions.

Learner
  • 319
  • 2
  • 4
  • 9
  • 1
    Why don't you make them all together unique? Wouldn't that solve the problem or am I misunderstanding something? I.e. `unique_together = ("instruction", "event_code", "scrap_code")` – yvesonline Dec 20 '19 at 08:10
  • So if I do this, It will be applicable for same instruction as well as different instructions as well?? My requirement is both codes should be unique for a particular instruction as well as different instructions also – Learner Dec 20 '19 at 08:12
  • Please add some sample instruction and code combinations which should be allowed or not allowed to your question so that it's clearer. If I understand correctly if `(1, A, B)` exists you want to disallow `(2, A, B)`? Where `()` is formatted like `(instruction, scrap_code, event_code)`. – yvesonline Dec 20 '19 at 08:18
  • Yes exactly, one scrap_code or event_code cannot be the part of multiple instructions. So if a scrap_code or event_code is there in Instruction 1 , it cannot be the part of instruction 2 – Learner Dec 20 '19 at 08:27
  • So then if they have to be unique across the model then make them unique with `unique_together = ("event_code", "scrap_code")`. – yvesonline Dec 20 '19 at 08:30
  • Yes but will it be applicable for a particular instruction? Like for a particular instruction I have make unique scrap_code or event_code with instruction so I put like unique_together = (("instruction", "event_code"), ("instruction", "scrap_code")) So it should be unique for particular instruction as well as unique across models means different instructions – Learner Dec 20 '19 at 08:32
  • 1
    If it's unique across the whole table that means automatically it'll be also unique to particular instructions you have. Please have a read of how unique constraints in SQL work, there are lot of resources available. Also then add unit tests to your implementation covering the different cases you have, this way you ensure your model is behaving the way you expect it to behave. – yvesonline Dec 20 '19 at 08:43
  • I tried to use unique_together = ('instruction', 'scrap_code', 'event_code' ) but it is still submitting in other instruction... – Learner Dec 20 '19 at 09:30
  • So I have added unique=True in Models so that the fields will be unique throughout the table. – Learner Dec 20 '19 at 13:44

2 Answers2

1

Try this

class ScrapEventInstructionMap(models.Model):
    instruction = models.ForeignKey(Instruction)
    scrap_code = models.CharField(max_length=100, null=True, blank=True)
    event_code = models.CharField(max_length=100, null=True, blank=True)

    class Meta:
        unique_together = (("event_code", "scrap_code"))
Gorkhali Khadka
  • 823
  • 8
  • 12
  • Yes I have used this approach. So I have 2 Instructions. So if the scrap_code and event_code in first Instruction matches with other instruction then I am unable to submit it. This is one criteria. But other is let we have scrap_code as 1 and event_codes a 11 and in other instruction if I am putting scrap_code as NULL or any other value and putting event_code as 11. It is submitting. Which should not be submitted. – Learner Dec 20 '19 at 09:41
  • So it should be unique even for 1 field. Now it is checking for both fields. If both fields match it is not submitting but even if one field is unique it is submitting. – Learner Dec 20 '19 at 09:47
  • And how can I give user some kind of comment to users that the event_code which you're trying to submit is already mapped with other instruction. Any hint to users would be enough in Admin Page – Learner Dec 20 '19 at 09:48
  • Brother its not working for same instruction also. For 1 instruction I am able to enter same scrap_code or event_code multiple times. – Learner Dec 20 '19 at 09:50
  • remove null=True and blank=True and make migrations that will not inserting null value – Gorkhali Khadka Dec 20 '19 at 09:52
  • Yes but if one field is same and other will be different. Then also it is submitting. Moreover for one particular instruction I am able to submit same scrap_code or event_code. So I used unique_together = (("instruction", "event_code"), ("instruction", "scrap_code")) so that for a particular instruction scrap_code and event_code should be different – Learner Dec 20 '19 at 09:54
  • So, I have added unique=True in Models so that the fields will be unique throughout the table. – Learner Dec 20 '19 at 13:44
1

You should add custom validation in BaseInlineFormSet of InlineAdmin. Here is example of BaseInlineFormSet validation.

ar7n
  • 171
  • 1
  • 6