Дизайн Django Models: отношение многих ко многим с конкретными потребностями - PullRequest
0 голосов
/ 24 апреля 2019

Я нахожусь в процессе разработки нескольких новых моделей для моего приложения django, и это то, что мне нужно:

class Bookmaker(models.Model):
  name = models.CharField(max_length=50)
  accepted_countries = ?
  restricted_countries = ?

class Country(models.Model):
  name = models.CharField(max_length=50)
  bookmakers = ?

Поэтому мне нужны модель Букмекерская контора и модель Страны, и они должны бытьсвязанные, НО каждый букмекер должен иметь список стран, которые принимаются и список стран, которые исключены.Знаки вопроса находятся как в модели Country, так и в моделях Bookmaker, так как я не уверен, в каком направлении должны развиваться отношения.

Не уверен, что я на правильном пути, но я думаю, что янужна пара отношений «многие ко многим». И как правильно (если таковые имеются) использовать одну и ту же модель Страны (это будут разные экземпляры) как в accept_countries, так и limited_countries?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

Тебе действительно нужно много-много:

class Bookmaker(models.Model):
  name = models.CharField(max_length=50)
  accepted_countries = models.ManyToMany('Country',related_name='accepted')
  restricted_countries = models.ManyToMany('Country', related_name= 'restricted')

class Country(models.Model):
  name = models.CharField(max_length=50)
  bookmakers = models.ManyToMany(Bookmaker)

Тогда, если вы создадите форму для редактирования букмекера, вы сможете добавить имя, допустимые и запрещенные страны:

forms.py

class BookmakerForm(models.ModelForm):
    class Meta:
        model = Bookmaker
        fields = ['name', 'accepted_countries', 'restricted_countries']

    #for having a better default display you can change the widget:
    self __init__(self, *args, **kwargs):
        super(BookmakerForm, self).__init__(*args, **kwargs)
        self.fields['accepted_countries'].widget = CheckboxSelectMultiple()
        self.fields['restricted_countries'].widget = CheckboxSelectMultiple()

В представлении по умолчанию, если вам просто нужно проверить, если form.is_valid() и сохранить. Модель django будет управлять промежуточным этапом для вас.

Поле букмекерских контор в Стране позволяет вам получить информацию обо всех букмекерских конторах, связанных с какой-либо страной, без необходимости регистрировать как принятые, так и ограниченные (это больше для удобства).

Но вам нужно будет добавить букмекера в этот список на вашем экране, например:

class CreateBookmakerView(CreateView):
    model = Bookmaker
    form_class = BookmakerForm
    success_url = reverse_lazy('your success url name here')

    def form_valid(self,form):
        bookmaker = form.save()
        bookmaker.country_set.add(bookmaker)
        bookmaker.save()
        return HttpResponseRedirect(self.get_success_url())
0 голосов
/ 24 апреля 2019

Вы должны использовать отношения два ко многим с related_name, чтобы разделить их:

class Bookmaker(models.Model):
    name = models.CharField(max_length=50)
    accepted_countries = models.ManyToManyField(Country, related_name="accepted_for")
    restricted_countries = models.ManyToManyField(Country, related_name="restricted_for")

Затем вы можете использовать обратное соотношение как:

bookmakers_for_which_county_is_accepted = Country.objects.values('accepted_for').distinct()
bookmakers_for_which_county_is_restricted = Country.objects.values('restricted_for').distinct()

* 1009 Docs *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...