Монти Холл и ленивые последовательности (?)

SlugRelatedField , предоставленный инфраструктурой Django REST, как и многие связанные с ним поля, предназначен для использования с уже существующими объектами. Поскольку вы ищете ссылку на объекты, которые уже существуют, или объект, который нужно создать, вы не сможете использовать его как есть.

Вам понадобится пользовательский SlugRelatedField, который создает новый объект, если его не существует.

class CreatableSlugRelatedField(serializers.SlugRelatedField):

    def to_internal_value(self, data):
        try:
            return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
        except ObjectDoesNotExist:
            self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
        except (TypeError, ValueError):
            self.fail('invalid')

class MerchantSerializer(serializers.ModelSerializer):
    phones = CreateableSlugRelatedField(
        many=True,
        slug_field='phone',
        queryset=primitives.Phone.objects.all()
    )

    class Meta:
        model = Merchant
        fields = (
            'merchant_id',
            'name',
            'is_active',
            'phones',
        )

При переключении на get_or_create объект номера телефона будет создан, если он еще не существует. Возможно, вам придется настроить его, если на модели будут созданы дополнительные поля.

1
задан Sol 3 March 2019 в 23:58
поделиться

2 ответа

Следуя решению @ TaylorWood , вы можете выразить обе свои функции более кратко, хотя я не уверен, что краткие версии так же ясны.

Ваша create-contest функция map проверяет каждое число i, чтобы узнать, является ли оно одним . Лучше просто поменять на напрямую. Для этого нам нужен вектор, который, я думаю, вы все равно захотите найти при моделировании игры:

 (defn create-contest [n]
  (assoc (vec (repeat n :closed)) (rand-int n) :car))

Ваша функция create-doors многократно передает один и тот же аргумент своему map ' с функцией. Вы можете использовать repeatedly на закрытии, чтобы получить тот же эффект:

(defn create-doors [doors contests]
  (repeatedly contests (partial create-contest doors)))

или

(defn create-doors [doors contests]
  (repeatedly contests #(create-contest doors)))
0
ответ дан Thumbnail 3 March 2019 в 23:58
поделиться

Вы очень близки, вы должны просто использовать форму let вместо def здесь:

(defn create-contest
  "Creates a monty hall doors contest"
  [n]
  (let [door-with-car (rand-int n)] ;; let instead of def
    (map
      (fn [i] (if (= i door-with-car) :car :closed))
      (range n))))

def свяжет некоторое значение с переменной в текущем пространстве имен, но Вы хотите связать значение в области действия этой функции, и для этого хорошо let. См. этот Q & A для другого объяснения.

(defn create-doors
  "Create a collection of monty hall contests"
  [doors contests]
  (map
    create-contest ;; no need to wrap create-contest in another function here
    (repeat contests doors)))

Вам не нужно заключать create-contest в другую функцию для использования с map - вы можете просто передать функцию непосредственно в map в качестве значения. doall необходим только для принудительной реализации отложенной последовательности из map, поэтому вам, вероятно, не нужно / не нужно этого внутри create-doors.

(create-doors 4 10)
=>
((:closed :closed :car :closed)
 (:closed :closed :closed :car)
 (:closed :car :closed :closed)
 (:closed :closed :closed :car)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :car :closed :closed)
 (:closed :closed :closed :car)
 (:closed :closed :car :closed)
 (:closed :closed :car :closed))
0
ответ дан Taylor Wood 3 March 2019 в 23:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: