Vra

Die gebruik van Django se gebou in modelle, hoe sou 'n mens skep 'n drie-sluit tussen drie modelle.

Byvoorbeeld:

  • Gebruikers, rolle, en gebeure is die modelle.
  • Gebruikers het baie rolle, en rolle baie gebruikers. (ManyToMany)
  • Events het baie gebruikers, en gebruikers baie Events. (ManyToMany)
  • Maar vir enige gegewe Event, kan enige gebruiker net een rol.

Hoe kan dit verteenwoordig in die model?

Was dit nuttig?

Oplossing

zacherates skryf:

  

Ek sal rol as 'n vereniging klas tussen gebruikers en rolle (...)

'n model

Ek wil ook reccomed hierdie oplossing, maar jy kan ook gebruik maak van 'n paar sintaktiese suiker verskaf deur Django maak: ManyToMany verhouding met ekstra velde .

Voorbeeld:

class User(models.Model):
    name = models.CharField(max_length=128)

class Event(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(User, through='Role')

    def __unicode__(self):
        return self.name

class Role(models.Model):
    person = models.ForeignKey(User)
    group = models.ForeignKey(Event)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

Ander wenke

Ek wil aanbeveel net die skep van 'n heeltemal aparte model vir hierdie.

class Assignment(Model):
    user = ForeignKey(User)
    role = ForeignKey(Role)
    event = ForeignKey(Event)

Dit laat jou doen al die gewone model dinge, soos

user.assignment_set.filter(role__name="Chaperon")
role.assignment_set.filter(event__name="Silly Walkathon")

Die enigste ding wat links is om jou een-rol per gebruiker per gebeurtenis-beperking af te dwing. Jy kan dit doen in die Opdrag klas deur óf oorheersende die red metode ( http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods ) of die gebruik van seine ( http://docs.djangoproject.com/en/dev/topics/signals/ )

Ek sal rolmodel as 'n vereniging klas tussen gebruikers en rolle, dus,

class User(models.Model):
     ...

class Event(models.Model):
     ...

class Role(models.Model):
     user = models.ForeignKey(User)
     event = models.ForeignKey(Event)

En dwing die een rol per gebruiker per gebeurtenis in óf 'n bestuurder of SQL beperkings.

Terwyl jy probeer om uit te vind 'n vinniger drie-tafel aan te sluit vir my eie Django modelle, het ek afgekom op hierdie vraag. By verstek, Django 1.1 gebruik INNER sluit wat stadig op InnoDB kan wees. Vir 'n soektog soos:

def event_users(event_name):
    return User.objects.filter(roles__events__name=event_name)

dit kan die volgende SQL skep:

SELECT `user`.`id`, `user`.`name` FROM `user` INNER JOIN `roles` ON (`user`.`id` = `roles`.`user_id`) INNER JOIN `event` ON (`roles`.`event_id` = `event`.`id`) WHERE `event`.`name` = "event_name"

Die binneste sluit kan baie stadig in vergelyking met die linker sluit. 'N nog vinniger navraag kan gevind word onder gimg1 se antwoord: MySQL navraag na drie tafels aan te sluit

SELECT `user`.`id`, `user`.`name` FROM `user`, `roles`, `event` WHERE `user`.`id` = `roles`.`user_id` AND `roles`.`event_id` = `event`.`id` AND `event`.`name` = "event_name"

Dit sal egter moet jy 'n persoonlike SQL navraag gebruik: https: //docs.djangoproject.com/en/dev/topics/db/sql/

In hierdie geval, sou dit iets soos kyk:

from django.db import connection
def event_users(event_name):
    cursor = connection.cursor()
    cursor.execute('select U.name from user U, roles R, event E' \
                   ' where U.id=R.user_id and R.event_id=E.id and E.name="%s"' % event_name)
    return [row[0] for row in cursor.fetchall()]
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top