2

我有 3 个模型类

  1. 旅游
  2. 游客
  3. 相片

为了能够将照片添加到游览中,用户必须注册游览。

我在管理面板“旅游”->“添加照片”表单中尝试做的是仅显示所选旅游中列出的游客列表。

最简单的方法是什么?

我的模型(大部分代码与问题无关,但我想它可能会有所帮助):

class Tourist(models.Model):

REQ_FIELDS = ["pk", "name", "email", "phone_number", "facebook_id",
              "phone_is_verified", "is_banned", "bus_id"]

name = models.CharField(max_length = 200)
email = models.EmailField()
phone_number = models.CharField(max_length = 30,
                                null=True,
                                blank=True,
                                default="")
facebook_id = models.CharField(max_length = 255,
                               null=True,
                               blank=True,
                               default="")
phone_verification_hash = models.CharField(max_length=100,
                                           blank=True,
                                           null=True,
                                           default="")
phone_is_verified = models.BooleanField(default = False)
is_banned = models.BooleanField(default = False)
backoffice_notes = models.CharField(blank=True, null=True, default="", max_length=250)
bus = models.ForeignKey(Bus, blank = True, null = True, related_name="tourists")
is_admin_added = models.BooleanField(default = False)

creation_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0))
modified_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0), auto_now=True)

lang = models.CharField(choices =(("he", "Hebrew"), ("en", "English"),), default = "he", max_length = 100)

def need_phone_verification(self):
    return bool(self.phone_number) and not self.phone_is_verified

def is_phone_verified(self):
    """
    can he receive sms?
    """
    return bool(self.phone_number) and self.phone_is_verified

def is_facebook_verified(self):
    return bool(self.facebook_id)

def login_is_verified(self):
    """
    can he upload photos?
    """
    return not self.is_banned and \
               (self.is_phone_verified() or self.is_facebook_verified()) or \
               self.is_admin_added

def verify_phone(self):
    ans = self.send_verification_code()
    return ans

def send_verification_code( self ):
    random.seed( timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()) )
    verify_code = str( int(random.random() * 9000 + 1000))

    if sms_verify_send( self.phone_number, verify_code ):
        self.phone_verification_hash = hashlib.sha1(verify_code).hexdigest()
        self.save()
    else:
        raise Exception("Bad SMS Server")
    return verify_code

def receive_verification_code( self, submitted_code ):
    if hashlib.sha1(submitted_code).hexdigest() == \
            self.phone_verification_hash:

        self.phone_is_verified = True
        self.save()
        return True
    return False

def __unicode__(self):
    return u"%s (%s, %s)" % ( self.name, self.email, self.phone_number )

def to_dict(self):
    obj = {}
    for field_name in self.REQ_FIELDS:
        obj[field_name] = getattr(self, field_name)
    return obj

def image_name(self):

    hebrew_test = any(u"\u0590" <= c <= u"\u05EA" for c in self.name)
    if hebrew_test:
        # if the name is in hebrew we flip it over so it will display 
        # correctly
        self.name= self.name[::-1]

    ans = self.name
    if self.is_phone_verified():
        if hebrew_test:
            ans = "(%s) %s" % (self.phone_number[-4:], self.name )
        else:
            ans = "%s (%s)" % (self.name, self.phone_number[-4:] )
    return ans

类旅游(模型。模型):

REQ_FIELDS = ["pk", "title", "start_time", "end_time", "display_order",
              "is_cancelled" ]

title = models.CharField(max_length = 200)
start_time = models.DateTimeField()
end_time = models.DateTimeField()
custom_logo = models.FileField(help_text="Please use a png file",
                               upload_to='media/tour_logo',
                               blank=True,
                               null=True,
                               validators=[is_png_ext])
display_order = models.IntegerField(choices = ((1, 'First in, First out'),
                                               (2, 'First in, Last out'),
                                               (3, 'Equal among users'),
                                               (4, 'Equal among busses')))
is_cancelled = models.BooleanField(default = False)

busses = models.ManyToManyField(Bus, blank=True, null=True, related_name = "tours")
tourists = models.ManyToManyField(Tourist, blank=True, null=True, related_name = "tours")
tourists_to_be_informed = models.ManyToManyField(Tourist, blank=True, null=True, related_name = "tours_to_be_informed")
transportation_company_provider = models.ForeignKey(Transportation_company, related_name = "tours")

backoffice_notes = models.CharField(blank=True, null=True, default="", max_length=250)

client = models.ForeignKey(Client, related_name="tours")

is_album_sent = models.BooleanField("Was the Album sent", default = False)

tourist_validator_mail = models.EmailField(blank=True, null=True)

creation_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0))
modified_date = models.DateTimeField(default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0), auto_now=True)

def is_valid(self):
    start = self.start_time
    # now = datetime.datetime.now()
    # we us time-zone aware time
    now = timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone())


    return start < now and not self.is_album_sent and not self.is_cancelled

def __unicode__(self):
    return u"%s" % self.title

def to_dict(self):
    obj = {}
    for field_name in self.REQ_FIELDS:
        obj[field_name] = getattr(self, field_name)
    return obj

def compare_date(self, curr ):
    """
    checks if time is before tour started ( then is with minus )
    or in the tour time ( with value 0 )
    or after ( with plus )
    """
    start = self.start_time
    end = self.end_time
    if curr < start:
        return -1
    if end < curr:
        return 1
    return 0

def began_and_running(self):
    # we us time-zone aware time
    time_now = timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone())
    began_and_running = self.start_time < time_now and self.photos.count() > 4
    return began_and_running

def inform(self):
    from views import contact
    if self.tourists_to_be_informed.count() > 0:
        if self.began_and_running():
            for tourist in self.tourists_to_be_informed.all():
                contact(tourist, "joined_past_notice", self)
                self.tourists_to_be_informed.remove(tourist)

def stats(self):
    return {"id": self.id,
            "title": self.title,
            "day_count": (self.end_time - self.start_time).days,
            "photo_count": self.photos.count(),
            "photo_removed_count": self.photos.filter(is_removed=True)
                                              .count(),
            "tourist_count": self.tourists.count()}

def album_link(self, tourist_id):
    query = Tour.encode_link(self.id, tourist_id)
    relative_url = build_url("pictours_app:album", get = {"query": query})

    msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
    return msg

def slideshow_link(self, tourist_id):
    query = Tour.encode_link(self.id, tourist_id)
    relative_url = build_url('pictours_app:slideshow', get = {"query": query})

    msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
    return msg

def transportation_company(self):
    tc = self.photos.exists() and self.photos.all()[0].bus.transportation_company
    return tc

def admin_link(self):
    relative_url = build_url('admin:pictours_app_touractive_change', args = (self.id,))

    msg = "http://%s%s" % (Site.objects.get_current().domain, relative_url)
    return msg

@staticmethod
def encode_link(tour_id, tourist_id):
    encoded = tour_id * BIG_PRIM_NUM + tourist_id
    return encoded

@staticmethod
def decode_link(query):
    int_query = query and int(query)
    pk = int_query / BIG_PRIM_NUM
    tourist_id = int_query % BIG_PRIM_NUM
    return (pk, tourist_id)

def validate_album_link(self):
    return self.album_link( -1 )

类照片(模型。模型):

REQ_FIELDS = ["pk", "s3_url"]

s3_url = models.URLField("Photo storage url", max_length=250)
s3_url_processed = models.ImageField("Processed photo",
                                     max_length=250,
                                     upload_to=Photo_upload_path,
                                     null = True)

s3_url_album = models.ImageField("Album size photo",
                                 max_length=250,
                                 upload_to=Photo_upload_path,
                                 null = True)

s3_url_thumbnail = models.ImageField("Thumbnail size photo",
                                     max_length=250,
                                     upload_to=Photo_upload_path,
                                     null = True)

tour = models.ForeignKey(Tour, related_name="photos")

tourist = models.ForeignKey(Tourist,
                            related_name="photos")

bus = models.ForeignKey(Bus, related_name="photos")

description = models.CharField("backoffice notes",
                               max_length=250,
                               null=True,
                               blank=True,
                               default="")

is_featured = models.BooleanField(default = False)
is_removed = models.BooleanField(default = False)
tourist_removed = models.ForeignKey( Tourist,
                                     related_name="removed_photos",
                                     verbose_name="Tourist who removed photo",
                                     help_text="Valid when photo is removed",
                                     null=True,
                                     blank=True)

creation_date = models.DateTimeField(
    default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0),
    editable=False)

# creation_date = models.DateTimeField(
#     default=lambda: datetime.datetime.now(pytz.timezone('US/Pacific')).replace(microsecond=0),
#     editable=False,
#     blank=True)



modified_date = models.DateTimeField(
    default=lambda: timezone.make_aware(datetime.datetime.now(),timezone.get_default_timezone()).replace(microsecond=0),
    auto_now=True)

def save(self, *args, **kwargs):
    from views import handle_photo
    self.bus = self.tourist.bus
    handle_photo(self, self.tour.client)
    self.tour.inform()
    super(Photo, self).save(*args, **kwargs)  # Call the "real" save() method.

def to_dict(self):
    obj = {}
    for field_name in self.REQ_FIELDS:
        obj[field_name] = getattr(self, field_name)
    return obj

def __unicode__(self):
    return u"<photo>tourist: %s @tour: %s" % (self.tourist, self.tour)
4

1 回答 1

0

Django admin 可以处理不同的用户权限:

https://docs.djangoproject.com/en/1.5/topics/auth/default/#permissions-and-authorization

不仅可以按对象类型设置权限,还可以按特定对象实例设置权限。通过使用 ModelAdmin 类提供的 has_add_permission()、has_change_permission() 和 has_delete_permission() 方法,可以为同一类型的不同对象实例自定义权限。

于 2013-10-06T11:01:58.470 回答